2012-05-06 722 views
15

如何將遮罩應用於最新python綁定(cv2)中的彩色圖像?在以前的python綁定中,最簡單的方法是使用例如cv.CopyOpenCV - 將遮罩應用於彩色圖像

cv.Copy(dst, src, mask)

但是這個功能是不是在CV2結合使用。有沒有使用樣板代碼的解決方法?

+0

你想做什麼?因爲它有numpy支持,所以你可以使用numpy函數。 –

+0

我正在做一些HSV色彩空間過濾到原始圖像 – pzo

回答

30

在這裏,如果您已經擁有蒙版圖像,則可以使用cv2.bitwise_and函數。

對於檢查以下代碼:

img = cv2.imread('lena.jpg') 
mask = cv2.imread('mask.png',0) 
res = cv2.bitwise_and(img,img,mask = mask) 

的輸出將是一個海倫圖像如下,並且爲矩形形狀的蔭罩。阿比德·拉赫曼給出K

enter image description here

+0

我正在嘗試做類似的事情。面膜應該是黑色還是白色?對於基本問題抱歉,我是opencv的新手。謝謝 –

+2

雅,你說得對,面罩應該是黑/白和單通道。無論您想要處理的圖像中的哪個區域,面罩中的這些區域都應該是白色的,其他所有區域都是黑色的。你不必爲這個問題而感到抱歉,每個人在開始學習時都是新手,甚至我也是。 –

+0

非常感謝阿比德!當我回到家時,我會嘗試這個夜晚。我必須將圖像分成幾個區域(並將這個過程重複成多個圖像)。問候! –

-1

答案不完全正確的。我也試過了,發現非常有幫助但被卡住了。

這是我如何複製圖像與給定的面具。

x, y = np.where(mask!=0) 
pts = zip(x, y) 
# Assuming dst and src are of same sizes 
for pt in pts: 
    dst[pt] = src[pt] 

這是有點慢,但給出正確的結果。

編輯:

Pythonic的方式。

idx = (mask!=0) 
dst[idx] = src[idx] 
+0

阿比德的答案有什麼不正確? – 2014-02-06 02:25:32

+0

當cv2中的「bitwise_and」方法按要求100%工作時,這裏不需要重新發明輪子。不僅如此,它的功能也非常明顯。 –

6

那麼,如果您希望背景不是純黑色,那麼這裏有一個解決方案。我們只需要反轉蒙版並將其應用於相同尺寸的背景圖像,然後合併背景和前景。這個解決方案的專家是背景可以是任何東西(甚至其他圖像)。

此示例從Hough Circle Transform修改。第一個圖像是OpenCV徽標,第二個是原始蒙版,第三個是後臺+前景合併。

apply mask and get a customized background

# http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_houghcircles/py_houghcircles.html 
import cv2 
import numpy as np 

# load the image 
img = cv2.imread('E:\\FOTOS\\opencv\\opencv_logo.png') 
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 

# detect circles 
gray = cv2.medianBlur(cv2.cvtColor(img, cv2.COLOR_RGB2GRAY), 5) 
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=50, minRadius=0, maxRadius=0) 
circles = np.uint16(np.around(circles)) 

# draw mask 
mask = np.full((img.shape[0], img.shape[1]), 0, dtype=np.uint8) # mask is only 
for i in circles[0, :]: 
    cv2.circle(mask, (i[0], i[1]), i[2], (255, 255, 255), -1) 

# get first masked value (foreground) 
fg = cv2.bitwise_or(img, img, mask=mask) 

# get second masked value (background) mask must be inverted 
mask = cv2.bitwise_not(mask) 
background = np.full(img.shape, 255, dtype=np.uint8) 
bk = cv2.bitwise_or(background, background, mask=mask) 

# combine foreground+background 
final = cv2.bitwise_or(fg, bk) 

注:這是更好地使用OpenCV的方法,因爲它們會被優化。

1

描述的其他方法假設一個二進制掩碼。如果你想用一個實值單通道灰度圖像作爲掩模(例如,從一個alpha通道),可以將其擴展到三個通道,然後用它進行插值:

assert len(mask.shape) == 2 and issubclass(mask.dtype.type, np.floating) 
assert len(foreground_rgb.shape) == 3 
assert len(background_rgb.shape) == 3 

alpha3 = np.stack([mask]*3, axis=2) 
blended = alpha3 * foreground_rgb + (1. - alpha3) * background_rgb 

注意mask需求在範圍0..1中操作成功。還假定1.0編碼只保留前景,而0.0表示只保留背景。

如果掩碼可以具有形狀(h, w, 1),這有助於:

alpha3 = np.squeeze(np.stack([np.atleast_3d(mask)]*3, axis=2)) 

這裏np.atleast_3d(mask)使面膜(h, w, 1)如果(h, w)np.squeeze(...)重塑結果從(h, w, 3, 1)(h, w, 3)