2015-11-24 139 views
2

我想基于面具的信息结合两个图像。如果蒙版为0,则使用背景图像中的颜色信息,如果蒙版为1,则使用前景图像中的颜色信息。因为蒙版和两个图像的大小相同,所以我想使用矩阵的逻辑索引为了达成这个。图像混合与面具

我尝试:

mask = imread('mask.png'); 
foreground = imread('fg.jpg'); 
background = imread('bg.jpg'); 
[r,c,~]=size(mask); 
A = zeros(size(mask)); 

for i=1:r  
    for j=1:c   
    if mask(i,j) == 0 
     A(i,j,:) = background(i,j,:); 
    end 
    if mask(i,j) > 0 
     A(i,j,:) = foreground(i,j,:); 
    end  
    end 
end 

imshow(A); 

结果看起来像一个闪烁的蓝色图像,但我不希望出现这种情况。请帮忙。

回答

2

您的代码有两个问题。第一个问题是您正尝试将颜色像素分配给输出图像A,但此图像仅为二维。你想要一个图像与三个渠道,而不是两个。另外,您指定的输出图像类型是错误的。默认情况下,输出图像A的类型为double,但您正在将值复制到其中,不是double ...最可能是无符号的8位整数。

因此,将图像投射到与输入图像相同的类型。假设两个输入图像是同一类型,初始化A使:

A = zeros(size(foreground), class(foreground)); 

这使得正确使用相同类型的任何输入的彩色图像,假设他们都是同一类型。

现在,您的for循环没问题,但如果您使用logical索引进行一次性操作,则效果会更好。如果您想使用logical建立索引,请创建一个像您所做的一样最初空白的新图像,但请确保您的蒙版有三个通道以匹配其他图像的通道数。之后,你只需要索引到每一个图像,并相应设置正确的位置:

mask = imread('mask.png'); 
foreground = imread('fg.jpg'); 
background = imread('bg.jpg'); 
[r,c,d]=size(mask); %// Change 

%// If your mask isn't three channels, make it so 
%// Change 
if d ~= 3 
    mask = cat(3, mask, mask, mask); 
end 

A = zeros(size(foreground), class(foreground)); %// Change 

A(mask) = foreground(mask); %// Assign pixels to foreground 
A(~mask) = background(~mask); %// Assign pixels to background 

imshow(A); 
+1

哈哈,完全忽略了图像并非黑白:D – lhcgeneva

+1

@lhcgeneva:D说实话,我几乎忘了,直到我更完整地阅读代码。 – rayryeng

3

你可以做到这一点多一点简洁:

f = double(foreground).*double(mask); 
b = double(background).*double(~mask); 
blend = f+b; 
imshow(blend, []); 

使用逻辑索引,还可以做

foreground(logical(mask)) = 0; 
background(logical(~mask)) = 0; 
blend = foreground+background; 

的状态并没有运营商“〜”反转的第二行矩阵,所以你剪出你想要背景的区域。

注意:这适用于黑色和白色(一个通道)。对于彩色图像,请参阅雷林的解决方案。

+0

我想用逻辑索引 – den

+0

可能比我有什么:)快了很多。 – rayryeng