2015-11-24 137 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