如何在MATLAB中创建复古图像?

3
给定一张彩色图片作为输入,我想要叠加三张相同大小的图片,并分别着上以下颜色:绿色、黑色和蓝色。
对于这些图片中的每一张,我想要改变它们的透明度:
- 绿色 = 40% - 黑色 = 43% - 蓝色 = 39%
创建这些图片后,我想最终将输入图片与38%的不透明度叠加。有谁能帮忙吗?我想使用MATLAB将原始图片应用这种复古效果。

你尝试过什么吗? - rayryeng
我尝试过,但效果很差。你认为我用这种方式获取复古图像的想法可行吗? - angel
我知道如何创建老式图像,但不是你所要求的方式。我从未使用这三种颜色的不透明度处理老式图像。我使用每个通道的RGB成分的加权组合来创建老式/棕褐色图像。你想让我用我的方法写一个答案吗? - rayryeng
是的,我会很感激。 :) 我的想法是使用Instagram创建相同的效果。 - angel
很酷 :) 给我一会儿。 - rayryeng
1个回答

4
我从未使用你所说的不透明度在图像上创建类似棕褐色/复古的效果。通常我用输入图像的红、绿和蓝通道的组合来创建棕褐色/复古图像的输出红、绿和蓝分量。使用以下方程式即可创建这种棕褐色/复古效果。假设您的输入图像的红、绿和蓝通道分别存储在inputRedinputGreeninputBlue中。这些是Microsoft推荐的方程式:
outputRed = (inputRed * .393) + (inputGreen *.769) + (inputBlue * .189)
outputGreen = (inputRed * .349) + (inputGreen *.686) + (inputBlue * .168)
outputBlue = (inputRed * .272) + (inputGreen *.534) + (inputBlue * .131)
来源: Tech Republic outputRedoutputGreenoutputBlue是深褐色/复古图像的输出颜色通道。因此,只需读入图像,然后提取每个颜色平面,对于每个输出颜色通道进行加权组合,然后将通道合并在一起即可。需要注意的是,当您读入图像时,这很可能是uint8类型。为了在乘以小数时保持精度,您需要在继续之前将图像转换为double。一旦计算出深褐色/复古色调通道,您需要将结果转换回uint8,以便正确显示图像并将其保存到磁盘。因此,以下是代码:
im = double(imread('...')); % // Read in your image here
inputRed = im(:,:,1); %// Extract each colour plane
inputGreen = im(:,:,2);
inputBlue = im(:,:,3);

%// Create sepia tones for each channel
outputRed = (inputRed * .393) + (inputGreen *.769) + (inputBlue * .189);
outputGreen = (inputRed * .349) + (inputGreen *.686) + (inputBlue * .168);
outputBlue = (inputRed * .272) + (inputGreen *.534) + (inputBlue * .131);

%// Create output image by putting all of these back into a 3D matrix
%// and convert back to uint8
out = uint8(cat(3, outputRed, outputGreen, outputBlue));

figure;
imshow(im,[]); %// Show original image
figure;
imshow(out); %// Show sepia image

请注意,要重新创建3D矩阵,我使用cat将数组/矩阵连接在指定的维度上。我指定了第三个维度,因为我们希望将红色、绿色和蓝色通道叠加在一起形成一个3D矩阵。然后我将此结果转换为uint8
这是一个例子。我决定从Jon Woodbury Photography拍摄一张家庭肖像照。这里出现的人我不认识,但还是谢谢你们让我使用你们的照片 :)

http://jonwoodburyphotography.com/blog/wp-content/gallery/12-best-family-portraits-of-2012/best-unique-family-portraits-utah-8544.jpg

当我下载这个图像后,再使用这个图像运行代码,下面是输出结果:

enter image description here


旁注 - 效率

上述代码需要输入相当多的内容。如果您愿意,可以使用 permutereshape 的组合来将其缩减为两行(如果考虑读取图像作为一步,则为三行)。 您需要将棕褐色系数封装在一个二维矩阵中,然后可以通过矩阵乘法计算每个输出像素。 因此:

im = double(imread('...')); %// Read in image
%// Define sepia matrix
M = [0.393 0.769 0.189; 0.349 0.686 0.168; 0.272 0.534 0.131];
out = uint8(reshape((M*reshape(permute(im, [3 1 2]), 3, [])).', ...
           [size(im,1) size(im,2), 3]));

您应该得到与代码先前版本相同的输出!作为测试,您在下面的评论中提供了一张图片:

这是我使用修改后的代码得到的结果(实际上,您将只会得到与代码第一个版本相同的结果):

enter image description here


谢谢。 :) 附言:你认为可以获得效果,就像你所能做的一样。http://i.ytimg.com/vi/14khxLI8j4U/maxresdefault.jpg - angel
@angel - 不好意思,你想对那张图片做什么?你想找出这个年代是什么样子的吗?无论如何,我已经为你完成了。请查看我的编辑后的帖子。 - rayryeng
与此同时,感谢您的可用性。我想应用像我发布的图像一样的效果。 - angel
让我解释一下。a)http://i46.photobucket.com/albums/f137/thanhtu_zx/Untitled-1.jpg b)http://i.ytimg.com/vi/14khxLI8j4U/maxresdefault.jpg 考虑到图a),例如对于a1),我想应用如图b)的过滤器。 - angel
@angel - 我无法复制那个。那些是 Instagram 的商业机密,这就是为什么他们通过应用程序赚钱的原因 :) 如果精确算法可以获得,那么 Instagram 就不会赚到任何钱 :). 这就是我帮不了你的地方。最接近古老/棕褐色的效果就是我上面所展示的。抱歉! 顺便祝你好运。 - rayryeng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接