目錄
1 灰度直方圖簡介
1.1 灰度直方圖概念
灰度直方圖(histogram)是灰度級的函數,描述的是圖像中每種灰度級像素的個數,反映圖像中每種灰度出現的頻率。其中,橫座標是灰度級,縱座標是灰度級出現的頻率。
1.2 灰度直方圖作用
1)在使用輪廓線確定物體邊界時,通過直方圖更好的選擇邊界閾值,進行閾值化處理;
2)對物體與背景有較強對比的景物的分割特別有用;
3)簡單物體的面積和綜合光密度IOD可以通過圖像的直方圖求得。
1.3 繪製的直方圖
假設存在一個 33 的圖像,如下圖所示,數組 統計的是像素點的灰度級,數組 統計的是具有該灰度級的像素個數。其中,灰度爲1的像素共3個,灰度爲2的像素共1個,灰度爲3的像素共2個,灰度爲4的像素共1個,灰度爲5的像素共2個。
= [1, 2, 3, 4, 5]
= [3, 1, 2, 1, 2]
根據上面的數據,繪製的直方圖如下所示:
如果灰度級爲0-255(最小值0黑色,最大值255白色),同樣可以繪製對應的直方圖,下圖是三張圖片拼接而成及其對應的直方圖。
1.4 歸一化直方圖
該直方圖的橫座標表示圖像中各個像素點的灰度級,縱座標表示出現這個灰度級的概率。其計算方法如下:
(1) 先計算灰度級及對應像素的個數
= [1, 2, 3, 4, 5]
= [3, 1, 2, 1, 2]
(2) 統計總的像素個數
= (3 + 1 + 2 + 1 +2) = 9
(3) 統計各個灰度級的出現概率
= = [3/9, 1/9, 2/9, 1/9, 2/9]
2 matplotlib庫 繪製直方圖-hist()
使用matplotlib的子庫pyplot實現,它提供了類似於Matlab的繪圖框架,matplotlib是非常強大基礎的一個Python繪圖包。其中繪製直方圖主要調用 hist() 函數實現,它根據數據源和像素級繪製直方圖。
hist()函數形式如下:
hist(數據源, 像素級)
其中,參數:
數據源:必須是一維數組,通常需要通過函數 ravel() 拉直圖像
像素級:一般是256,表示[0, 255]
函數 ravel() 將多維數組降爲一維數組,其格式爲:
一維數組 = 多維數組.ravel()
代碼如下所示:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('zxp.jpg')
cv2.imshow("src", src)
plt.hist(src.ravel(), 256)
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
運行結果如下圖所示:
上述是調用 matplotlib庫 中的hist() 函數來繪製直方圖,接下來介紹使用OpenCV庫中的calcHist() 函數繪製直方圖。
3 OpenCV庫 繪製直方圖-calcHist()
使用OpenCV庫中的 calcHist() 函數來繪製直方圖:
hist = cv2.calcHist(images, channels, mask, histSize, ranges, accumulate)
其中,參數:
hist 表示直方圖,返回的是一個二維數組;
images 表示原始圖像;
channels 表示指定通道,通道編號需要用中括號括起,輸入圖像是灰度圖像時,它的值爲[0],彩色圖像則爲[0]、[1]、[2],分別表示B、G、R;
mask 表示掩碼圖像,統計整副圖像的直方圖,設爲None,統計圖像的某一部分直方圖時,需要掩碼圖像;
histSize 表示BINS的數量,參數子集的數目,如下圖當bins=3表示三個灰度級;
ranges 表示像素值範圍,例如[0, 255];
accumulate 表示累計疊加標識,默認爲false,如果被設置爲true,則直方圖在開始分配時不會被清零,該參數允許從多個對象中計算單個直方圖,或者用於實時更新直方圖;多個直方圖的累積結果用於對一組圖像的直方圖計算。
(1)計算圖像灰度級的基本大小、形狀及內容
代碼如下所示:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('zxp.jpg')
# 參數:原圖像 通道[0]-B 掩碼 BINS爲256 像素範圍0-255
hist = cv2.calcHist([src], [0], None, [256], [0,255])
print('type=',type(hist))
print('size=',hist.size)
print('shape=',hist.shape)
print("-------------------")
print('hist=',hist)
運行結果如下圖所示:
由上面的結果可知:
(1)直方圖是一個數組;
(2)大小爲256,;
(3)形狀爲256行,1列的數組。
(2)補充:matplotlib庫 繪製圖像
代碼如下所示:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#繪製sin函數曲線
x1 = np.arange(0, 6, 0.1)
y1 = np.sin(x1)
plt.plot(x1, y1)
#繪製座標點折現
x2 = [0, 1, 2, 3, 4, 5, 6]
y2 = [0.3, 0.4, 2.5, 3.4, 4, 5.8, 7.2]
plt.plot(x2, y2)
#省略有規則遞增的x2參數
y3 = [0, 0.5, 1.5, 2.4, 4.6, 8]
plt.plot(y3, color="r")
plt.show()
運行結果如下圖所示:
(3)使用OpenCV庫 中的 calcHist() 函數 計算B、G、R通道的灰度級並繪製圖形
代碼如下所示:
#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
src = cv2.imread('zxp.jpg')
histb = cv2.calcHist([src], [0], None, [256], [0,255])
histg = cv2.calcHist([src], [1], None, [256], [0,255])
histr = cv2.calcHist([src], [2], None, [256], [0,255])
cv2.imshow("src", src)
plt.plot(histb, color='b')
plt.plot(histg, color='g')
plt.plot(histr, color='r')
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
運行結果如下圖所示:
參考資料
[1] https://blog.csdn.net/Eastmount/article/details/83758402