2015-05-19 495 views
13

我正在嘗試從圖像中提取紅色。我有適用的閾值從指定的範圍只留下值碼:使用Python和OpenCV查找紅色

img=cv2.imread('img.bmp') 
img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 
lower_red = np.array([0,50,50]) #example value 
upper_red = np.array([10,255,255]) #example value 
mask = cv2.inRange(img_hsv, lower_red, upper_red) 
img_result = cv2.bitwise_and(img, img, mask=mask) 

但是,正如我檢查,紅色可以在範圍色調值,比方說從0到10,以及在範圍從170到180.因此,我想留下這兩個範圍中的任何一個值。我嘗試設置閾值從10到170,並使用cv2.bitwise_not函數,但我也得到了所有的白色。我認爲最好的選擇是爲每個範圍創建一個掩碼並使用它們,所以我不知何故必須在繼續之前將它們結合在一起。

有沒有一種方法可以使用OpenCV加入兩個蒙版?還是有其他方式可以實現我的目標?

編輯。我來沒有太大的優雅,但工作液:

image_result = np.zeros((image_height,image_width,3),np.uint8) 

for i in range(image_height): #those are set elsewhere 
    for j in range(image_width): #those are set elsewhere 
     if img_hsv[i][j][1]>=50 \ 
      and img_hsv[i][j][2]>=50 \ 
      and (img_hsv[i][j][0] <= 10 or img_hsv[i][j][0]>=170): 
      image_result[i][j]=img_hsv[i][j] 

它幾乎滿足了我的需求,和OpenCV的功能可能做的是幾乎相同的,但如果有更好的方法來做到這一點(使用一些專用功能和寫更少的代碼)請與我分享。 :)

回答

15

我只是將面具添加在一起,並使用np.where來掩蓋原始圖像。

img=cv2.imread("img.bmp") 
img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV) 

# lower mask (0-10) 
lower_red = np.array([0,50,50]) 
upper_red = np.array([10,255,255]) 
mask0 = cv2.inRange(img_hsv, lower_red, upper_red) 

# upper mask (170-180) 
lower_red = np.array([170,50,50]) 
upper_red = np.array([180,255,255]) 
mask1 = cv2.inRange(img_hsv, lower_red, upper_red) 

# join my masks 
mask = mask0+mask1 

# set my output img to zero everywhere except my mask 
output_img = img.copy() 
output_img[np.where(mask==0)] = 0 

# or your HSV image, which I *believe* is what you want 
output_hsv = img_hsv.copy() 
output_hsv[np.where(mask==0)] = 0 

這應該比循環瀏覽圖像的每個像素要快得多並且更具可讀性。

+3

如果有人感興趣。我正在使用嵌入式設備,如樹莓派。下一個操作ID對於這樣的設備非常重: output_img [np.where(mask == 0)] = 0。 它可以用更快的代替: output_img = cv2.bitwise_and(output_img,output_img,mask = mask) –