這篇教學會介紹使用 OpenCV 的 inrange() 方法,指定一個色彩範圍,抓取影像中符合色彩範圍內的顏色,透過這個方式,就可以篩選出影像中的特定顏色物件。
原文參考:抓取影像的特定顏色
因為程式中的 OpenCV 會需要使用鏡頭或 GPU,所以請使用本機環境 ( 參考:使用 Python 虛擬環境 ) 或使用 Anaconda Jupyter 進行實作 ( 參考:使用 Anaconda ) ,並安裝 OpenCV 函式庫 ( 參考:OpenCV 函式庫 )。
使用 OpenCV 的 inrange() 方法,可以指定一個色彩的最低數值與最高數值 ( 使用 NumPy 陣列 ),抓取符合這個色彩範圍內的所有像素成為新影像 ( 範圍外的像素都會被過濾掉 ),使用方法如下:
cv2.inRange(img, lowerb, upperb)
# img 來源影像
# 色彩範圍最低數值
# 色彩範圍最高數值
舉例來說,如果要擷取攝影機畫面中的紅色瓶蓋,可以先觀察並記錄瓶蓋的紅色區間 ( 透過其他繪圖軟體 ),區間約略在紅色 252 左右,綠色 70~80 之間,藍色 55~70 之間。
下方的例子,將色彩選取的範圍加大,搭配影像遮罩,就能將擷取出紅色的瓶蓋的部分。
參考:影像遮罩
import cv2
import numpy as np
lower = np.array([30,40,200]) # 轉換成 NumPy 陣列,範圍稍微變小 ( 55->30, 70->40, 252->200 )
upper = np.array([90,100,255]) # 轉換成 NumPy 陣列,範圍稍微加大 ( 70->90, 80->100, 252->255 )
img = cv2.imread('oxxo.jpg')
mask = cv2.inRange(img, lower, upper) # 使用 inRange
output = cv2.bitwise_and(img, img, mask = mask ) # 套用影像遮罩
cv2.imwrite('output.jpg', output)
cv2.waitKey(0) # 按下任意鍵停止
cv2.destroyAllWindows()
延伸「讀取並播放影片」文章的範例,就能即時獨立出攝影機影片中的瓶蓋。
import cv2
import numpy as np
lower = np.array([30,40,200]) # 轉換成 NumPy 陣列,範圍稍微變小 ( 55->30, 70->40, 252->200 )
upper = np.array([90,100,255]) # 轉換成 NumPy 陣列,範圍稍微加大 ( 70->90, 80->100, 252->255 )
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("Cannot open camera")
exit()
while True:
ret, frame = cap.read()
if not ret:
print("Cannot receive frame")
break
mask = cv2.inRange(frame, lower, upper) # 使用 inRange
output = cv2.bitwise_and(frame, frame, mask = mask ) # 套用影像遮罩
cv2.imshow('oxxostudio', output)
if cv2.waitKey(1) == ord('q'):
break # 按下 q 鍵停止
cap.release()
cv2.destroyAllWindows()
大家好,我是 OXXO,是個即將邁入中年的斜槓青年,我已經寫了超過 400 篇 Python 的教學,有興趣可以參考下方連結呦~ ^_^