РЕДАКТИРОВАТЬ: извините за неправильное понимание вашего вопроса вчера, так что вот ваша полноцветная версия: P
Основная идея почти такая же, как у MATLAB: объединить два изображения в градациях серого с разными альфа-каналами, но в вашем случае есть еще несколько маневров. нужно, чтобы получить правильные вещи.
Во-первых, воссоздайте свою хорошо описанную ситуацию с предоставленными образцами.
% load foreground image, and scale to [-50, 300]
Foreground = imread('500x_54.jpg');
figure(1)
imshow(Foreground)
Foreground = im2double(Foreground)*350-50;
% load background image
Background = im2double(imread('2-effect1-500x225.jpg'));
figure(2)
imshow(Background)
Затем сделайте альфа-канал с нуля. Обратите внимание, что я не использую imagesc
, а пишу простой двойной массив. Это действительно альфа-канал! Не нужно столько загадок.
% build alpha layer for Foreground
alpha = bsxfun(@times, ones(size(Foreground,1), size(Foreground,2)), .6);
alpha(:,[1:53,149:203,290:352,447:end])=0;
alpha([1:58,170:end],:)=0;
figure(3)
imshow(alpha)
Перед смешиванием я хочу масштабировать передний план «назад» до [0,1]
. Поскольку фоновое изображение загружается из обычного изображения, его нормализация не требуется; только передний план в диапазоне от -50 до 300.
Проблема в том, что иногда у вас есть сумасшедшие данные, такие как -100
или 1000
. Я не знаю, как вы хотите их интерпретировать. Если вы принимаете [-50. 300]
за обычный, типичный диапазон, то как вы сопоставляете -100
или 1000
с уровнем цвета?
Есть 2 варианта/метода для решения этой проблемы: 1) Использовать [-100, 1000]
в качестве нового масштаба. Таким образом, -100
будет чисто черным и 1000
чистым цветом; 2) Продолжайте использовать [-50, 300]
в качестве диапазона масштаба, поэтому все элементы за пределами этого диапазона будут сопоставлены (принудительно) к ближайшей границе.
Здесь я выбираю первый, с адаптивным механизмом, который ограничивает диапазон не менее [-50, 300]
. Таким образом, если ваши данные имеют вид [-10,200]
, вы все равно получите шкалу [-50, 300]
. Я думаю, что это имеет больше смысла.
% find a scale dynamically with some limit
Foreground_min = min( min(Foreground(:)), -50 );
Foreground_max = max( max(Foreground(:)), 300 );
Процедура смешивания почти такая же, как в этом посте. Но вы используете изображения RGB, поэтому вам нужно add
числа для всех трех цветовых слоев; bsxfun
используется для замены более медленных операций +
и .*
.
% overlay the image by blending
Background_blending = bsxfun(@times, Background, bsxfun(@minus,1,alpha));
% Background_blending = Background.*repmat((1-alpha), 1, 1, 3);
Foreground_blending = bsxfun( @times, bsxfun( @rdivide, ...
bsxfun(@minus, Foreground, Foreground_min), ...
Foreground_max-Foreground_min ), alpha );
% Foreground_blending = (Foreground-Foreground_min) / ...
% (Foreground_max-Foreground_min).*repmat(alpha, 1, 1, 3);
% out = bsxfun(@plus, Background_blending, Foreground_blending);
out = Background_blending + Foreground_blending;
figure(4)
imshow(out)
Закомментированные строки, кроме первой, представляют собой «обычные» команды назначения без использования bsxfun
, но выполняют ту же работу и их легче понять :)
Результат
person
Yvon
schedule
15.08.2014