OpenCV:擷取顏色的技巧,抓出想要的顏色!

- OpenCV
目錄
有時候靠著 Image Processing 就可以解決的問題
就不用勞煩 AI 出手啦
這次要講的是擷取特定顏色的方法
擷取顏色
擷取顏色在辨識某樣物品或文字的時候很好用
可以把該樣物品對應的顏色範圍都擷取出來,後續再做處理

原圖

成果圖
首先我們讀取圖片並使用 cv2.cvtColor
把讀取進來的圖片轉成 HSV 格式
因為 HSV 格式能更好地擷取我們想要的顏色
img = cv2.imread('test.jpg')
cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
再來設定好想要的顏色範圍
hsv_color1 = np.asarray([20, 100, 50]) # 深橘色
hsv_color2 = np.asarray([40, 255, 255]) # 亮綠色
並使用 cv2.inRange
擷取我們設定好的顏色範圍
cv2.inRange(img_hsv, hsv_color1, hsv_color2)
下圖就是我們抓到的範圍

白色為擷取到的部分
有了遮罩後,使用 cv2.bitwise_and
依照遮罩拿取我們原圖的資料
先是 img
和 img
做 AND,再依照遮罩拿取
由於自己和自己做 AND 一樣是自己,所以就只有依照遮罩拿取
cv2.bitwise_and(img, img, mask=mask)
最後使用 cv2.cvtColor
轉成 matplotlib 使用的 RGB 格式
cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
這邊為全部程式碼:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('test.jpg')
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) # 將圖片從 BGR 格式轉成 HSV 格式
hsv_color1 = np.asarray([20, 100, 50]) # 深橘色
hsv_color2 = np.asarray([40, 255, 255]) # 亮綠色
mask = cv2.inRange(img_hsv, hsv_color1, hsv_color2) # 擷取顏色
result = cv2.bitwise_and(img, img, mask=mask) # 將原圖套用遮罩
result_rgb = cv2.cvtColor(result, cv2.COLOR_BGR2RGB) # 轉換格式至 RGB
plt.imshow(result_rgb) # 設定顯示圖片
plt.axis('off') # 關閉顯示座標軸
plt.show() # 顯示擷取的部分
色階圖
知道了如何提取顏色,但到底我想要的顏色對應的 HSV 又是多少呢?
下面我們就把 HSV 所有的數值都印出來
來看看到底每個數值對應到的顏色是甚麼吧 ~
我們輸入的圖一共有 2 種格式:
分別為 uint8 的整數格式和 float32 的浮點數格式
兩者 HSV 的範圍有點不一樣
因為 uint8 的範圍大小最多到 255,裝不下色相的 360
因此 / 2 變成 0 ~ 179
uint8:
- H: 0 ~ 179
- S: 0 ~ 255
- V: 0 ~ 255
float32:
- H: 0 ~ 359
- S: 0.0 ~ 1.0
- V: 0.0 ~ 1.0
下面我們就使用 2D 圖片把數值印出來,並附上印出來的程式碼
分別為:
- 色相 vs 飽和度
- 色相 vs 亮度
色相 vs 飽和度
Uint8 格式 (X軸: 色相,Y軸: 飽和度) Float32 格式 (X軸: 色相,Y軸: 飽和度)
import matplotlib.pyplot as plt
import numpy as np
import cv2
shape = (256, 180, 3)
img = np.zeros(shape, dtype=np.uint8)
for i in range(180):
for j in range(256):
img[j,i] = [i, j, 255]
img = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)
plt.imshow(img)
plt.xlabel('Hue')
plt.ylabel('Saturation')
plt.title('Value = 255')
plt.show()
色相 vs 亮度
Uint8 格式 (X軸: 色相,Y軸: 亮度) Float32 格式 (X軸: 色相,Y軸: 亮度)
import matplotlib.pyplot as plt
import numpy as np
import cv2
shape = (256, 180, 3)
img = np.zeros(shape, dtype=np.uint8)
for i in range(180):
for j in range(256):
img[j,i] = [i, 255, j]
img = cv2.cvtColor(img, cv2.COLOR_HSV2RGB)
plt.imshow(img)
plt.xlabel('Hue')
plt.ylabel('Value')
plt.title('Saturation = 255')
plt.show()
Reference
如果你覺得這篇文章有用 可以考慮贊助飲料給大貓咪