王全勝
摘要:顏色是物體的一種重要特征,人們可以依據(jù)顏色對物體進行分類、判斷等。顏色識別很大程度上改變著人們的工作方式。使用計算機對顏色進行識別,可以極大地提高工作效率,降低工作成本。本文就opencv中使用HSV模型對紅色識別過程中存在的識別不準確、不全面的情況進行了分析并提出解決方法,并在實踐中加以驗證。
關鍵詞:opencv;顏色識別;紅色;hsv python
中圖分類號:TP18? ? ? 文獻標識碼:A
文章編號:1009-3044(2021)25-0112-02
計算機視覺是使用計算機的攝像設備采集圖像并進行識別,并從圖像中獲取信息的人工智能系統(tǒng)。簡單的說,就是不但讓計算機學會看,還讓他知道看到了什么。以人看到的圖像為例,我們可以從中辨認出形狀、顏色、大小、亮度、色彩等。讓計算機辨認出特定的顏色,就是顏色識別。顏色是物體的一種重要特征,人們可以依據(jù)顏色對物體進行分類、判斷等。利用顏色特征,人們在很多行業(yè)的應用中獲得了便利。比如,在快遞行業(yè),依據(jù)不同的顏色對流水線上的物品進行分揀;在農業(yè),利用顏色識別判斷果蔬的成熟程度、對異常作物進行定位、藥物噴灑和進行田間雜草和作物的區(qū)分(智能除草);在公共安全方面,對火焰顏色的識別。大到衛(wèi)星遙感監(jiān)控山火,小到倉庫火災預警,顏色識別很大程度上改變著人們的工作方式。使用計算機對顏色進行識別,可以極大地提高工作效率,降低工作成本。視覺識別技術目前在工業(yè)檢測、生物醫(yī)學、X射線圖像增強、遙感圖像分析和空間技術等方面具有廣泛的應用價值。
1 顏色識別的方法
顏色識別主要有兩種方法,一種利用顏色模型識別,另一種采用訓練分類器的方法識別,第一種方法穩(wěn)定性并不高,經(jīng)常調節(jié)白平衡,即Gamma值,來適應色溫的變化,第二種方法也會受到未分類的特殊情況的影響,根據(jù)具體應用情況,擇優(yōu)選擇。彩色圖像的顏色模型有很多種形式,RGB、YUV、HSV、CMYK等,其中在圖像處理以RGB最為直觀理解且顯示器系統(tǒng)采用就是此類模型,而HSV更符合人眼的顏色分辨,通常在HSV顏色空間下進行顏色識別。HSV分別指色相、飽和度、亮度。色相就是“是什么顏色”,飽和度就是顏色有多濃,亮度就是圖像的明暗程度。
以HSV模型為例,它將顏色空間的模型對應于圓柱坐標系中的一個圓錐形子集,圓錐的頂面對應于V=1。它包含RGB模型中的R=1,G=1,B=1 三個面,所代表的顏色較亮。色彩H由繞V軸的旋轉角給定。紅色對應于角度0°,綠色對應于角度120°,藍色對應于角度240°。
識別顏色的算法是讀取照片像素點的顏色,轉換成HSV模型中的值,看它是否在要識別的顏色區(qū)間內。把在此顏色區(qū)間內的點的集合作為掩模,與原照片按位進行與運算,就得出了要尋找的顏色區(qū)域。舉個例子。我們要識別藍色的范圍,就把像素點轉換成HSV模型。對照圖一,看是否H(色相)在100至124之間,S(飽和度)是否在43至255之間,V(亮度)是否在46至255之間。如果同時滿足這三個條件,我們就認為這個像素點是藍色。這比較好理解。在實際的識別中,根據(jù)光線不同,這三個值會有稍許偏差。
2 識別紅色的特殊之處
在使用無人機機載攝像頭對色塊進行識別、判斷形狀的過程中我們發(fā)現(xiàn)紅色的識別成功率明顯小于其他顏色。通過抓取掩模我們看到,本應是紅色的區(qū)域掩模沒有完全覆蓋。通過圖一的表我們可以看到紅色的范圍并不是連續(xù)的范圍。它的H分布在0至10以及156至180。這兩個范圍的顏色都是紅色,因為其分布在HSV模型中不連續(xù),所以我們在給定顏色區(qū)間時只能給定其中一個。
3 掩模的抓取
我們使用python的opencv來做了實驗。首先,我們選擇了一張有色彩漸變的圖片作為實驗素材。
如圖2,我們選擇了一張聯(lián)想的彩色羽毛壁紙作為素材。將0至10范圍內的紅色掩模(圖3)和156至180范圍內的紅色掩模(圖4)進行了對比。
如圖4所示,兩組掩碼并不重合,但對應在圖2上的區(qū)域都是紅色。只要將兩塊區(qū)域合并再與圖二做按位與操作,就能得到圖二中的紅色區(qū)域。
4 算法
有了想法,我們用python寫了一段代碼來實現(xiàn)。代碼中使用了opencv和numpy。
import cv2
import numpy as np
def color_area(img, colors, thresholds):
"""
Args:
img:經(jīng)過濾波的BGR圖像
colors(list):需要分割的顏色
thresholds(dict):顏色的閾值
Returns:
mask(dict):{"顏色"(str):掩膜(二值圖)}
"""
masks = {}
img_hsv=cv2.cvtColor(img, cv2.COLOR_BGR2HSV)? ? #將圖像轉換成HSV模型
for color in colors:
low = thresholds[color][0]
high = thresholds[color][1]
mask = cv2.inRange(img_hsv,low,high)
s = np.sum(mask)? # 判斷掩膜是否全黑(沒有對應顏色)
if s == 0 :
mask = None
masks[color] = mask