OpenCV中的圖像處理 —— 直方圖大章(查找、繪制及分析+均衡化+二維直方圖+直方圖反投影)

      網友投稿 999 2022-05-29

      OpenCV中的圖像處理 —— 直方圖大章(查找、繪制及分析+均衡化+二維直方圖+直方圖反投影)

      關于直方圖在計算機視覺領域的地位、基本介紹和應用范圍在我的這篇文章中曾有提及,感興趣的小伙伴可以去康康:進入Computer Vision世界 —— 數字圖像 + 插值算法 + 直方圖 + 卷積&濾波

      我們可以將直方圖視為圖形或繪圖,從而可以總體了解圖像的強度分布,它是在X軸具有像素值(不一定是0~255),在Y軸上具有圖像中相應像素數的圖,通過直方圖我們可以直觀地了解圖像的對比度、明暗程度和強度分布等信息

      1. 直方圖的查找、繪制及分析

      1.1 尋找直方圖

      關于直方圖的查找,不管是OpenCV庫還是Numpy都提供了相應的方法

      OpenCV和Numpy中的直方圖計算

      OpenCV提供了一個cv.calcHist()函數用來查找直方圖,其中一般需要傳入5個參數:cv.calcHist(images,channels,mask,histSize,ranges [)

      第一個參數img是uint8或float3類型的源圖像

      第二個參數指的是計算直方圖的通道索引,如果輸入的是灰度圖,我們另其為[0]即可,對于彩色圖像[0/1/2]分別表示計算藍、綠和紅色通道的直方圖

      第三個參數是圖像掩碼,如果我們需要的是完整圖像的直方圖,則將其定義為None即可,如果我們需要查找的是特定區域內的直方圖,我們就必須為此創建一個掩碼圖像并將其作為掩碼傳入函數

      第四個參數histSize指的是直方圖中每個像素值的像素類型個數,對于全尺寸傳入[256]即可

      第五個參數ranges,顧名思義就是像素值范圍,全范圍即[0,256]

      Numpy提供了一個np.histogram()函數用于計算直方圖

      hist,bins = np.histogram(img.ravel(),256,[0,256])

      hist與我們之前計算的相同。但是bin將具有257個元素,因為Numpy計算出bin的范圍為 0-0.99 、1-1.99 、 2-2.99 等。因此最終范圍為 255-255.99 。為了表示這一點,他們還在最后添加了256。但是我們不需要256,最多255就足夠了

      除此之外Numpy還提供了一個更快的函數np.bincount(),它比np.histogram()快了十倍,對于一維直方圖這種方法無疑是更好的選擇,在使用的時候不要忘記在np.bincount中設置minlength = 256

      hist = np.bincount(img.ravel(),minlength = 256)

      說起運算速度我們不得不說OpenCV函數比np.histogram()大約快了40倍,因此我們要盡可能地使用OpenCV內置的函數

      1.2 繪制直方圖

      在前一塊兒我們說了用OpenCV的calcHist()函數和Numpy的np.bincount()或np.histogram()函數查找直方圖,在查找完畢之后我們還要把它繪制出來,使我們能更清晰地看到圖像的信息,關于直方圖的繪制有兩種方法供我們使用,分別是matplotlib庫的繪圖功能和OpenCV的繪圖功能,使用OpenCV提供的cv.line()函數和cv.ployline()可以幫助我們繪制直方圖,但是這種方法太過于繁瑣了,所以不建議使用

      Matplotlib繪制直方圖

      Matplotlib帶有直方圖繪圖功能: matplotlib.pyplot.hist() 它直接找到直方圖并將其繪制,我們甚至無需使用calcHist()或np.histogram()函數來查找直方圖便可直接繪制

      import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread('home.jpg',0) plt.hist(img.ravel(),256,[0,256]); plt.show()

      對于BGR圖像,我們可通過Matpllotlib的法線圖來繪制

      import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread('home.jpg') color = ('b','g','r') for i,col in enumerate(color): histr = cv.calcHist([img],[i],None,[256],[0,256]) plt.plot(histr,color = col) plt.xlim([0,256]) plt.show()

      老規矩為了更深刻地理解,我們先來分析一下代碼,1-4行就不用說了,不明白的同學可以去我的主頁翻翻之前的內容,第5行是定義了一組枚舉類型的數據,分別表示三個顏色通道,然后用了一個for循環來完成直方圖的查找和繪制

      第7行我們見到了cv.calchist()函數的返回值histr,它表示的是一個256*1的數組,每一個元素保存的是相應像素值的像素點個數,第8行的plt.plot()函數就值得一說了:

      它的原型是這樣的plt.plot(x, y, format_string, **kwargs) ,它用于對繪制的圖像作出一些修改,x和y分別表示軸上的數據,通常傳入列表或數組,format_string表示控制曲線的格式字符串,可選,由顏色字符、風格字符和標記字符組成,最后一個就是一些公共屬性了,比如顏色、粗細和線條風格等

      掩碼的應用

      上面我們無論是查找直方圖還是繪制直方圖,針對的都是完整的圖像,但是如果我們想要特定區域內的一塊兒圖像的直方圖呢?這個時候就會用到掩碼,我們需要先創建一個掩碼圖像,我們要找的直方圖為白色,其他地方為黑色

      img = cv.imread('home.jpg',0) # create a mask mask = np.zeros(img.shape[:2], np.uint8) mask[100:300, 100:400] = 255 masked_img = cv.bitwise_and(img,img,mask = mask) # 計算掩碼區域和非掩碼區域的直方圖 # 檢查作為掩碼的第三個參數 hist_full = cv.calcHist([img],[0],None,[256],[0,256]) hist_mask = cv.calcHist([img],[0],mask,[256],[0,256]) plt.subplot(221), plt.imshow(img, 'gray') plt.subplot(222), plt.imshow(mask,'gray') plt.subplot(223), plt.imshow(masked_img, 'gray') plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask) plt.xlim([0,256]) plt.show()

      2. 直方圖均衡

      2.1 了解均衡化

      有這樣一副圖像,它的像素值僅局限于某個特定區域的范圍,較亮的圖像將把所有像素限制在高值上,但是一幅好的圖像會有來自圖像所有區域的像素,因此您需要將這個直方圖拉伸到兩端,這就是直方圖均衡化的作用(簡單來說),這通常會提高圖像的對比度,也就是說我們需要一個轉換函數,將亮的區域的輸入像素映射到整個區域的輸出像素

      即使圖像是一個較暗的圖像,而不是我們使用的一個較亮的圖像,經過均衡后,我們將得到幾乎相同的圖像,因此,這是作為一個“參考工具”,使所有的圖像具有相同的照明條件

      在人臉識別中,在對人臉數據進行訓練之前,對人臉圖像進行直方圖均衡化處理,使其具有相同的光照條件

      2.2 OpenCV中的直方圖均衡

      OpenCV提供了了cv.equalizeHist()函數,它的輸入只是灰度圖像,輸出是我們的直方圖均衡圖像

      import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread(r'E:\image\test07.png', 0) equ = cv.equalizeHist(img) res = np.hstack((img, equ)) # stacking images side-by-side cv.imshow('res.png', res) cv.waitKey(0) cv.destroyWindow()

      這個例子就很明顯啦,原圖像由于天空亮度太高,我們甚至是看不到云的,但是在使用直方圖均衡化后,圖像的對比度明顯增強了,我們也可以很輕易的看到更多的圖像信息了

      當圖像的直方圖限制在特定區域時,直方圖均衡化效果很好。在直方圖覆蓋較大區域(即同時存在亮像素和暗像素)的強度變化較大的地方,效果并不理想

      2.3 CLAHE對比度受限的自適應均衡

      剛才我們演示的直方圖均衡化是針對的是整個圖像,然而在明暗差距較大時圖像處理效果并不好,也就是說有時候輸入圖像及其在全局直方圖均衡化的結果會導致亮度過亮或暗度過暗而導致一些圖像信息的丟失

      為了解決這個問題,我們會用到自適應直方圖均衡,在這種情況下圖像被分成稱為為“tiles”的小塊(在OpenCV中,tileSize默認為 8x8 )。然后,像往常一樣對這些塊中的每一個進行直方圖均衡,因此在較小的區域中,直方圖將限制在一個較小的區域中(除非存在噪聲),如果有噪聲的存在,直方圖均衡化操作會把噪聲放大,為了限制這種錯誤我們使用對比度限制,如果任何直方圖bin超出指定的對比度限制(在OpenCV中默認為40),則在應用直方圖均衡之前,將這些像素裁剪并均勻地分布到其他bin,均衡后,要消除圖塊邊界中的偽影,請應用雙線性插值

      為什么我們用全局均衡化就不行,而分割成小塊就可以了呢?聰明的同學已經猜到了,說明在執行均衡化處理的時候,也就是把原圖像的像素值映射到新圖像的時候,肯定是有操作涉及到全部像素的處理,這個時候運算可能就顧及不到所有像素的感受,因此才會出現一些圖像信息丟失的結果,關于直方圖均衡化和雙線性插值的原理可以看看我的這篇文章:進入Computer Vision世界 —— 數字圖像 + 插值算法 + 直方圖 + 卷積&濾波

      import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread(r'E:\image\test15.png', 0) clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) cl1 = clahe.apply(img) img2 = cv.equalizeHist(img) plt.subplot(1, 3, 1), plt.imshow(img, cmap='gray') plt.title('Original Image'), plt.xticks([]), plt.yticks() plt.subplot(1, 3, 2), plt.imshow(img2, cmap='gray') plt.title('Equalize Hist'), plt.xticks([]), plt.yticks() plt.subplot(1, 3, 3), plt.imshow(cl1, cmap='gray') plt.title('CLAHE Image'), plt.xticks([]), plt.yticks() plt.show()

      這樣效果就很明顯啦,使用全局直方圖均衡化會導致第二張圖的情況,人臉太亮了都看不清了,但是使用自適應均衡化的話呈現了第三張圖的效果,嘎嘎猛

      3. 二維直方圖

      上面兩部分我們學習的是一維直方圖,為什么呢?因為我們只涉及到了一個特征鴨,那就是像素的灰度強度值,但是在二維直方圖中我們需要考慮兩個特征,通過它用于查找顏色直方圖,這兩個特征而分別是每個像素的色相和飽和度值

      3.1 OpenCV中的二維直方圖

      嘿嘿,是不是正迷惑HSV呢?玩兒了太久的BGR和RGB都快把HSV顏色空間忘了吧,我們所需要的兩個特征色相和飽和度就正是其中的兩個通道,如果想復習一下HSV那就來看看這篇文章吧:HSVy顏色空間

      使用OpenCV查找二維直方圖依舊使用cv.calcHist()函數,只是需要改變其中傳入的參數而已,對于顏色直方圖當然要把BGR轉換為HSV咯

      第一個參數是HSV顏色通道的圖像,第二個參數是通道channel,此時我們需要傳入[0, 1],因為我們需要同時處理H和S平面,第三個參數是掩碼就不多說了,第四個參數bins是某像素值的像素類型個數,此時傳入[180, 256],第五個參數range傳入[0, 180, 0, 256]

      import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread(r'E:\image\test15.png', 0) hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV) hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])

      3.2 Numpy中的二維直方圖

      Numpy還為此提供了一個特定的函數:np.histogram2d(),第一個參數是H平面,第二個是S平面,第三個是每個箱子的數量,第四個是它們的范圍

      import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread('home.jpg') hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV) hist, xbins, ybins = np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])

      3.3 二維直方圖的繪制

      使用matplotlib繪制

      OpenCV中的圖像處理 —— 直方圖大章(查找、繪制及分析+均衡化+二維直方圖+直方圖反投影)

      import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread('home.jpg') hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV) hist = cv.calcHist( [hsv], [0, 1], None, [180, 256], [0, 180, 0, 256] ) plt.imshow(hist,interpolation = 'nearest') plt.show()

      4. 直方圖反投影

      4.1 了解直方圖反投影

      先來看看直方圖反投影是個啥,它用于圖像分割或在圖像中查找感興趣的對象,也就是是它創建的圖像大小與輸入圖像一致,但只有一個通道,其中每個像素對應于該像素屬于我們物體的概率

      我們創建一個圖像的直方圖,其中包含我們感興趣的對象,對象應盡可能填充圖像以獲得更好的效果,而且顏色直方圖比灰度直方圖更可取,因為對象的顏色對比灰度強度是定義對象的好方法

      然后,我們將該直方圖“反投影”到需要找到對象的測試圖像上,換句話說,我們計算出屬于背景的每個像素的概率并將其顯示出來,在適當的閾值下產生的輸出使我們僅獲得背景

      4.2 OpenCV中的反投影

      OpenCV提供了一個內建的函數cv.calcBackProject(),它的參數幾乎與cv.calchist()函數相同,它的一個參數是直方圖,也就是物體的直方圖,所以我們要查找直方圖,另外,在傳遞給backproject函數之前,應該對對象直方圖進行歸一化。它返回概率圖像。然后我們用圓盤內核對圖像進行卷積并應用閾值

      import numpy as np import cv2 as cv roi = cv.imread('rose_red.png') hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV) target = cv.imread('rose.png') hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV) # 計算對象的直方圖 roihist = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] ) # 直方圖歸一化并利用反傳算法 cv.normalize(roihist,roihist,0,255,cv.NORM_MINMAX) dst = cv.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1) # 用圓盤進行卷積 disc = cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5)) cv.filter2D(dst,-1,disc,dst) # 應用閾值作與操作 ret,thresh = cv.threshold(dst,50,255,0) thresh = cv.merge((thresh,thresh,thresh)) res = cv.bitwise_and(target,thresh) res = np.vstack((target,thresh,res)) cv.imwrite('res.jpg',res)

      AI OpenCV 圖像處理 機器學習 機器視覺

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:萬字直通面試:Flink雙流JOIN
      下一篇:開發者測試-采用精準測試工具對Spring Boot應用進行測試
      相關文章
      亚洲美免无码中文字幕在线| 亚洲码国产精品高潮在线| 国产国拍亚洲精品福利 | 国产国拍亚洲精品福利| 亚洲国产人成精品| 亚洲爆乳少妇无码激情| 亚洲AV男人的天堂在线观看| 亚洲不卡在线观看| 亚洲的天堂av无码| 亚洲国产成人va在线观看网址| 亚洲色图视频在线观看| 亚洲福利秒拍一区二区| 亚洲成人高清在线观看| 亚洲1234区乱码| 亚洲中文字幕一二三四区苍井空 | 国产精品亚洲色婷婷99久久精品| 亚洲国产成人精品无码区二本 | 亚洲国产成人久久精品动漫| 久久伊人久久亚洲综合| 亚洲成a人片77777老司机| 亚洲男人的天堂在线播放| 久久亚洲精品成人AV| 亚洲高清中文字幕综合网| 亚洲综合激情九月婷婷| 亚洲国产中文在线二区三区免| 亚洲深深色噜噜狠狠网站| 亚洲女子高潮不断爆白浆| 亚洲av无码av在线播放| 亚洲av成人一区二区三区在线观看| 国产亚洲高清在线精品不卡| 免费在线观看亚洲| 久久亚洲国产成人精品无码区| 亚洲色成人WWW永久网站| 久久久亚洲精品视频| 久久精品蜜芽亚洲国产AV| 亚洲一区在线视频| 亚洲AV成人片无码网站| 亚洲精品无码日韩国产不卡?V| 亚洲一区二区三区AV无码| 亚洲欧洲日产国码久在线观看| 亚洲免费视频观看|