Python OpenCV 圖像處理之直方圖相關(guān)知識細節(jié),學點細的

Python OpenCV 365 天學習計劃,與橡皮擦一起進入圖像領(lǐng)域吧。本篇博客是這個系列的第 50 篇。
該系列文章導航參考:https://blog.csdn.net/hihell/category_10688961.html

@[toc](Python OpenCV)

學在前面

直方圖在之前的博客中已經(jīng)學習過一部分內(nèi)容了,具體可以自行去回顧。


2021030107105987[1].png

直方圖是圖像處理過程中的一個分析工具,是使用灰度值或者從灰度級的角度統(tǒng)計圖像的特征。

如果從統(tǒng)計的角度看,直方圖統(tǒng)計了圖像各個灰度級出現(xiàn)的次數(shù),直方圖橫坐標是像素灰度級,縱坐標是該灰度級的個數(shù)。

如果存在一個 5x5 的灰度圖,那直方圖就是對其中的各個像素值進行統(tǒng)計。

20210301071609132[1].png

20210301071823707[1].png

上面 2 張圖就是關(guān)于直方圖統(tǒng)計的說明,但直方圖直觀的呈現(xiàn)不是表格,而是圖形,所以將上述數(shù)據(jù)進行繪制,即可得到直方圖。
直方圖中 x 軸表示的是 8 位位圖的 256 個灰度級,y 軸表示的是對應灰度級的像素點格式。

基于此還要補充一個知識,叫做歸一化的直方圖,在很多時候,直方圖中 x 軸表示灰度級,但是 y 軸表示灰度級出現(xiàn)的頻率,具體就是將次數(shù)/總數(shù),例如上表可以修改為:


20210301091903656[1].png

直方圖概念理解之后,還有幾個新詞需要注意下,DIMS、BINS、RANGE

  • DIMS:基于目前知識,只有一個灰度值,該值為 1,它表示的是收集直方圖時,收集的參數(shù)數(shù)量;
  • RANGE:統(tǒng)計灰度級范圍,對于灰度圖,范圍是 [0,255];
  • BINS:參數(shù)子級數(shù)目,大概含義可以理解為,將剛才的灰度級做分組處理,一般保持默認即可。

對于 BINS 參數(shù)在細說一下,對于灰度圖像,灰度級的區(qū)間是 [0,255],其 BINS 默認是 256,如果按照 16 個灰度級為一組,可以分為 16 個 BINS。

直方圖繪制

Python OpenCV 圖像處理之圖像直方圖,取經(jīng)之旅第 25 天 本篇博客已經(jīng)對直方圖的繪制進行了說明,先來整體回顧一下。

代碼基于 plt.hist() 函數(shù)實現(xiàn)直方圖,該函數(shù)原型為 plt.hist(X,BINS)

運行下述代碼,找圖片的時候,盡量找顏色分布比較平均的,不要白色或者黑色所占區(qū)域特別大,否則得到的直方圖效果不明顯。

import cv2 as cv
import matplotlib.pyplot as plt

src = cv.imread("./2.png", 0)
cv.imshow("src", src)

plt.hist(src.ravel(), 256)
plt.show()

cv.waitKey()
cv.destroyAllWindows()
202103010936265[1].png

上述代碼還有一個需要注意的就是 src.ravel() 函數(shù)了,該函數(shù)用于將二維數(shù)組降成一維數(shù)組,例如下圖所示。

20210301094129638[1].png

如果將 BINS 設(shè)置為 16 得到的結(jié)果如下。

20210301094245925[1].png

Python OpenCV 中的直方圖繪制

在 OpenCV 中使用 cv.calcHist 函數(shù)計算圖像的直方圖,本文重點說明一下該函數(shù)的返回值。

import cv2 as cv
import matplotlib.pyplot as plt

src = cv.imread("./2.png", 0)
cv.imshow("src", src)
hist = cv.calcHist([src], [0], None, [256], [0, 255])
print(hist)
print(len(hist))
cv.waitKey()
cv.destroyAllWindows()

hist 輸出格式如下:

# 省略一部分輸出數(shù)據(jù)
……
 [ 115.]
 [ 122.]
 [ 115.]
 [ 142.]
 [ 148.]
 [ 152.]
 [  61.]
 [   6.]
 [   0.]]
256

可以看到最后返回的 hist 是 256 個數(shù)字組成的數(shù)組,該數(shù)組內(nèi)的元素是各個灰度級的統(tǒng)計個數(shù)。
得到 hist 之后,就可以通過 plt.plot 函數(shù)將其繪制出來啦。

import cv2 as cv
import matplotlib.pyplot as plt

src = cv.imread("./2.png", 0)
cv.imshow("src", src)
ret_hist = cv.calcHist([src], [0], None, [256], [0, 255])
print(ret_hist)
print(len(ret_hist))
plt.plot(ret_hist)
plt.show()
cv.waitKey()
cv.destroyAllWindows()

202103010959520[1].png

掩膜繪制直方圖

接下來說明一下掩膜繪制直方圖,通過掩膜就是選擇圖像的一部分區(qū)域進行繪制,掩膜白色區(qū)域表示透明,可顯示圖片,黑色區(qū)域表示不透明,無法顯示圖片。

掩膜的原理也可以翻閱以前的博客進行學習,總結(jié)下來就是下面兩句話

  1. 原圖像與掩膜中黑色位置對應的部分,這部分就不再顯示了,灰度值被置為 0;
  2. 原圖像與掩膜中白色位置對應的部分,保留原值。
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
src = cv.imread("./2.png", 0)
cv.imshow("src", src)
print(src.shape)
mask = np.zeros(src.shape, np.uint8)
# 前面是行,后面是列
mask[10:150, 40: 200] = 255
mask_img = cv.bitwise_and(src, mask)
cv.imshow("mask", mask_img)
ret_hist = cv.calcHist([src], [0], None, [256], [0, 255])
mask_hist = cv.calcHist([src], [0], mask, [256], [0, 255])

plt.plot(ret_hist)
plt.plot(mask_hist)
plt.show()
cv.waitKey()
cv.destroyAllWindows()
20210301101619598[1].png

直方圖均衡化相關(guān)知識補充

直方圖均衡化,可以使圖像擁有全部可能的灰度級,讓像素值的灰度均勻分布,實現(xiàn)的具體步驟如下。

  1. 計算累計直方圖
  2. 對累計直方圖進行轉(zhuǎn)換

可以參考下述灰度矩陣,該圖像大小為 5x5,具有 8 個灰度級,范圍是 [0,7],計算歸一化的統(tǒng)計直方圖與累計統(tǒng)計直方圖分別如下。

20210301114657482[1].png

基于上圖,可以對原有灰度級空間進行轉(zhuǎn)換,分為兩種一種是在原有的灰度空間范圍,即 [0,7],第二種是在更大范圍進行轉(zhuǎn)換。

首先看一下在原有范圍內(nèi)實現(xiàn)均衡化,用當前的累計概率乘以 7(灰度級的最大值),得到新的灰度級。

20210301115046491[1].png

新灰度級與原灰度級個數(shù)可以對比得出。

未均衡化之前,灰度級如果區(qū)分成 2 組,數(shù)據(jù)如下:

  1. 0~3:4 個像素點,統(tǒng)計的像素個數(shù)是 19;
  2. 4~7:4 個像素點,統(tǒng)計的像素個數(shù)是 6。
    均衡化之后,灰度級如果區(qū)分成 2 組,數(shù)據(jù)如下:
  3. 0~3:4 個像素點,統(tǒng)計的像素個數(shù)是 11;
  4. 4~7:4 個像素點,統(tǒng)計的像素個數(shù)是 14。

如果希望得到更大范圍的直方圖,只需要將累計概率乘以更大的灰度級即可,具體可以自行嘗試。

橡皮擦的小節(jié)

希望今天的 1 個小時你有所收獲,我們下篇博客見~

相關(guān)閱讀


技術(shù)專欄

  1. Python 爬蟲 100 例教程,超棒的爬蟲教程,立即訂閱吧
  2. Python 爬蟲小課,精彩 9 講

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容