前文提醒:博主正在參加博客之星評比,成功入選Top200,現在暫居第九歡迎各位點擊了解更多幫我投票,非常感謝~
目錄
「python opencv 計算機視覺零基礎實戰」 第一節
「python opencv視覺入門到實戰」二、格式與攝像頭
「python opencv 視覺入門到實戰」 三、圖像編輯
「python opencv視覺入門到實戰」 第四節色彩空間
「python opencv視覺入門到實戰」 五、對象追蹤
「python opencv視覺零基礎到實戰」 六、圖像運算
「python opencv視覺零基礎實戰」 七邏輯運算應用
「python opencv視覺零到實戰」 八、圖片選區操作
「python opencv計算機視覺零基礎到實戰」 九模糊
「python opencv視覺零基礎」 十、圖片效果毛玻璃
「python opencv視覺零基礎」 十一、指定內容查找
「python opencv 視覺零基礎」 十二、 直方圖
「python opencv視覺零基礎」十三、圖片顏色提鮮
一、學習目標
了解了直方圖反向投影的一般流程了解2D直方圖的使用如有錯誤歡迎指出~
二、了解直方圖反向投影
2.1 了解2D直方圖
需要對直方圖進行反向投影,需要使用2D直方圖。2D直方圖需要使用calcHist方法。calcHist方法在前兩節中已經有了解,現在再來複習一下。首先我們查看calcHist方法的原型。
calcHist(images; channels; mask; histSize; ranges[; hist[; accumulate]])calcHist方法中images參數為所需要傳入的圖像,接受類型為uint8以及float32,參入參數時可以使用[]對參數進行標記;channels為傳入的通道數;mask為一個遮罩,如果為None則表示對全圖進行操作,若選擇其中一個部分就需要製作一個遮罩對局部進行操作;histSize為一個範圍,或者說是BIN的數目;ranges表示像素值範圍。
我們要繪製一個顏色直方圖的話,需要對BGR色彩空間進行轉換,轉換為HSV:
import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread(r'C:\Users\mx\Desktop\1.jpg')hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)隨後我們使用calcHist方法傳入數值,這個時候channels應該為[0,1],mask我們依舊為None,因為我們需要處理全圖;而histSize則表示了兩個通道,H以及S,所以應該寫成[180,256],即H通道為180,S通道為256,最後一個range則為[0,180,0,256],表示H取值範圍在和S的取值範圍。那麼整體的代碼如下:
import cv2import numpy as npfrom matplotlib import pyplot as pltimg = cv2.imread(r'C:\Users\mx\Desktop\1.jpg')hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)hist = cv2.calcHist([hsv], [0,1], None, [180,256], [0,180,0,256])plt.imshow(hist, interpolation='nearest')plt.show()結果如下:
2.2 了解直方圖反向投影
直方圖反向投影可以在圖像中找到我們感應區的部分,直方圖反向投影將會輸出模板圖像中類似的部分,越亮的的部分則表示得越白。我們需要完成這個操作首先得有一張需要查找的對象,隨後需要一張圖為查找區域。我們可以先對需要查找目標的圖像創建一個直方圖,隨後進行歸一化處理。歸一化處理使用normalize方法。首先我們進行讀取圖片與轉換HSV色彩空間圖,也順帶一起讀取目標掃描的圖片,原圖和目標圖、代碼如下:原圖:
目標圖:
roi = cv2.imread(r'C:\Users\mx\Desktop\gz\roi.png')hsv_roi = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)target = cv2.imread(r'C:\Users\mx\Desktop\gz\4.png')hsv_target = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)隨後對hsv_roi 感興趣的部分進行2D直方圖處理:
roihist = cv2.calcHist([hsv_roi],[0, 1], None, [180, 256], [0, 180, 0, 256] )接下來使用normalize方法進行歸一化;歸一化是將數據達到一種可進行對比的標準,但是保持了原有數據間的關係。代碼為:
cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)其中roihist為輸入數據,roihist為與src大小相同的輸出數據,0為一個範圍低邊界,255為範圍的上限,cv2.NORM_MINMAX是一個歸一化的方法,表示對數組的所有值進行轉化,使值的映射在最小值和最大值之間。這樣歸一化後他們的值就在0到255之間了。接著我們使用calcBackProject方法,calcBackProject方法與calcHist的參數類似。 cvCalcBackProject 用於計算直方圖的反向投影,得到的結果是數組在某個分布下的概率。
dst = cv2.calcBackProject([hsv_target],[0,1],roihist,[0,180,0,256],1) 隨後使用getStructuringElement方法進行卷積,把分散點連接:
gSEE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))dst=cv2.filter2D(dst,-1,gSEE)接著使用閥值方法:
ret,thresh = cv2.threshold(dst,50,255,0)最後進行合併:
trh = cv2.merge((trh,trh,trh))完整代碼如下:
import cv2import numpy as npfrom matplotlib import pyplot as pltroi = cv2.imread(r'C:\Users\mx\Desktop\gz\roi.png')hsv_roi = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)target = cv2.imread(r'C:\Users\mx\Desktop\gz\4.png')hsv_target = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)roihist = cv2.calcHist([hsv_roi],[0, 1], None, [180, 256], [0, 180, 0, 256] )cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)dst = cv2.calcBackProject([hsv_target],[0,1],roihist,[0,180,0,256],1)gSEE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))dst=cv2.filter2D(dst,-1,gSEE)ret,trh = cv2.threshold(dst,50,255,0)trh = cv2.merge((trh,trh,trh))cv2.imshow('trh',trh)cv2.waitKey(0)cv2.destroyAllWindows()結果如下:
當然我們也可以進行位運算,這樣我們就可以取出顏色部分了,所有完整代碼如下:
import cv2import numpy as npfrom matplotlib import pyplot as pltroi = cv2.imread(r'C:\Users\mx\Desktop\gz\roi.png')hsv_roi = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)target = cv2.imread(r'C:\Users\mx\Desktop\gz\4.png')hsv_target = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)roihist = cv2.calcHist([hsv_roi],[0, 1], None, [180, 256], [0, 180, 0, 256] )cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)dst = cv2.calcBackProject([hsv_target],[0,1],roihist,[0,180,0,256],1)gSEE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))dst=cv2.filter2D(dst,-1,gSEE)ret,trh = cv2.threshold(dst,50,255,0)trh = cv2.merge((trh,trh,trh))cv2.imshow('trh',trh)res = cv2.bitwise_and(target,trh)cv2.imwrite('res.jpg',res)cv2.imshow('res',res)cv2.waitKey(0)cv2.destroyAllWindows()結果如下:
我們也可以換一下圖:roi:
目標:
結果:
前文提醒:博主正在參加博客之星評比,成功入選Top200,現在暫居第九歡迎各位點擊了解更多幫我投票,非常感謝~