Я никогда не создавал эффекты сепии/винтажа на изображении, используя непрозрачность, о которой вы говорите. Что я обычно делаю для создания сепии/винтажных изображений, так это создание выходных красных, зеленых и синих компонентов, используя комбинацию красного, зеленого и синего каналов входного изображения.
Таким образом, вы создаете сепию / винтажные изображения, используя следующие уравнения. Предположим, что ваши красный, зеленый и синий каналы для входного изображения хранятся в inputRed
, inputGreen
и inputBlue
соответственно. Вот уравнения, рекомендованные Microsoft:
outputRed = (inputRed * .393) + (inputGreen *.769) + (inputBlue * .189)
outputGreen = (inputRed * .349) + (inputGreen *.686) + (inputBlue * .168)
outputBlue = (inputRed * .272) + (inputGreen *.534) + (inputBlue * .131)
Источник: Технологическая Республика
outputRed
, outputGreen
, outputBlue
— выходные цветовые каналы для сепии/винтажного изображения. Таким образом, просто прочитайте свое изображение, затем извлеките каждую из цветовых плоскостей, выполните эту взвешенную комбинацию для каждого из выходных цветовых каналов, затем объедините каналы вместе. Следует отметить, что когда вы читаете изображение, оно, скорее всего, будет иметь тип 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
Обратите внимание, что для повторного создания трехмерной матрицы я использую cat
, который объединяет массивы/матрицы в указанном измерении. Я указал третье измерение, так как мы хотим наложить красный, зеленый и синий каналы друг на друга, чтобы сформировать трехмерную матрицу. Затем я привел этот результат к uint8
.
Вот пример. Я решил взять семейный портрет с сайта Jon Woodbury Photography. Тех, кто появляется здесь, я не знаю лично, но тем не менее спасибо, что разрешили использовать вашу фотографию :)
http://jonwoodburyphotography.com/blog/wp-content/gallery/12-best-family-portraits-of-2012/best-unique-family-portraits-utah-8544.jpg
Когда я загружаю это изображение, а затем запускаю код с этим изображением, я получаю следующий результат:
Примечание — Эффективность
Приведенный выше код довольно много для ввода. Вы можете сделать это в две строки (три, если вы рассматриваете чтение изображения как шаг), если хотите, используя комбинацию permute
и reshape
< /а>. Вам нужно будет инкапсулировать коэффициенты сепии в 2D-матрицу, затем вы можете вычислить каждый выходной пиксель как умножение матрицы. В качестве таких:
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]));
Вы должны получить на выходе то же самое, что и в предыдущей версии кода! В качестве теста вы предоставили изображение в комментариях ниже:
Вот что я получаю, используя модифицированный код (на самом деле вы просто получите те же результаты, что и в первой версии кода):
person
rayryeng
schedule
09.09.2014