直方圖是圖像處理過程中的一種非常重要的分析工具。 是圖像內灰度值的統計特性與灰度值之間的函數,直方圖統計圖像內各個
灰度級出現的次數
需要注意三個概念:
DIMS : 表示繪制直方圖時,收集的參數的數量,一般情況下,直方圖中收集的數據只有一種,就是灰度級,因此該值為1
RANGE :表示統計的灰度級的范圍,一般為[0 . 255] . 0對應的時黑色,255對應的時白色
BINS : 參數子集的數目,在處理數據的過程中,有時需要將眾多的數據划分為若干個組,在進行分析
該圖中,BINS為6,RANGE為[2,6]
python 的模塊matplotlib.pyplot中的hist()函數能方便的繪制直方圖,
函數形式為
matplotlib.pyplot.hist( x , BINS)
x,為數據源 ,必須是一維的,圖像通常都是二維的, 可以通過函數ravel()來將二維數組降成一維的
例如:圖像x
23 | 34 | 14 |
54 | 63 | 23 |
45 | 25 | 76 |
對其使用函數ravel()
y = x.ravel()
得到y為:
23 | 34 | 14 | 54 | 63 | 23 | 45 | 25 | 76 |
BINS為灰度級的分組情況
繪制圖像的直方圖
1 import cv2 2 import matplotlib.pyplot as plt 3 o = cv2.imread("/home/miao/dog.jpg") 4 cv2.imshow("original" , o) 5 plt.hist(o.ravel() , 256) 6 cv2.waitKey() 7 cv2.destroyAllWindows() 8 plt.show()
這里要有函數plt.show()才會顯示出直方圖
圖像
直方圖
將灰度級划分為16個子集
opencv提供了函數,cv2.calcHist() 用來計算圖像的統計直方圖,
函數形式:
hist = cv2.calcHist( images , channels , mask , histSize , ranges , accumulate)
hist 返回統計直方圖,是一個一維數組,數組內的元素時各個灰度級的個數
images 原始圖像 需要用 [ ] 括起來
channels 指定通道編號, 也需要用[ ] 括起來,灰度圖像即為 [ 0 ] , 對於彩色圖像即為 [ 0 ] [ 1 ] [ 2 ] 對應的即為 B G R 通道
mask掩模圖像, 不需要時 則設置為None
histSize BINS值需要用[ ] 括起來
ranges像素值范圍, 例如8位灰度圖像范圍為 [ 0 , 256 ]
accumulate 累計默認值為False , 如果設置為True時, 計算的是多個直方圖的累計結果
plot()函數繪制圖像的直方圖
color = 'b' 表示曲線是藍色的 color = ' g' 表示曲線為綠色 color = 'r'表示曲線為紅色
1 import cv2 2 import matplotlib.pyplot as plt 3 o = cv2.imread("/home/miao/dog.jpg") 4 histb = cv2.calcHist([o] , [0] , None , [256] , [0,255]) 5 print(type[histb]) 6 print(histb.shape) 7 peitn(histb.size) 8 plt.plot(histb , color = 'b') 9 plt.show()
<class 'numpy.ndarray'> (256, 1) 256
返回類型為ndarray
數據為256列 1行
有256個元素
使用掩模繪制直方圖
1 import cv2 2 import numpy as np 3 import matplotlib.pyplot as plt 4 image = cv2.imread("/home/miao/dog.jpg" , cv2.IMREAD_GRAYSCALE) 5 mask = np.zeros( image.shape , np.uint8) 6 mask[100:200 , 50:150] = 255 7 histImage = cv2.calcHist([image] , [0] , None , [256] , [0,255] ) 8 histMi = cv2.calcHist( [image] , [0] , mask , [256] , [0,255]) 9 plt.plot(histImage) 10 plt.plot(histMi) 11 plt.show()
掩模之前有描述過就不再多說
直方圖的均衡化
目地主要是將原始圖像的灰度級均勻的映射到整個灰度級范圍內,得到一個灰度級均勻的圖像
實現方法為,將該灰度級出來的概率累計之前灰度級的概率之和 ,然后乘以最大灰度值,所得即為均衡化圖像
1 import cv2 2 import matplotlib.pyplot as plt 3 img = cv2.imread("/home/miao/dog.jpg" , cv2.IMREAD_GRAYSCALE) 4 equ = cv2.equalizeHist(img) 5 cv2.imshow("original" , img) 6 cv2.imshow("result" , equ) 7 plt.figure("原始圖像直方圖") 8 plt.hist(img.ravel() , 256) 9 plt.figure("均衡化結果直方圖") 10 plt.hist(equ.ravel() , 256) 11 plt.show() 12 cv2.waitKey() 13 cv2.destroyAllWindows()
原圖
直方圖均衡化處理
原始圖像直方圖
均衡化結果直方圖
可以看出原圖左側比較密集整體較高 , 在均衡化處理之后 左側變得稀疏 ,右側密集 , 整體來看是比較均衡的
函數matplotlib.pyplot.subplot( nrows , ncols , index)
例如:subplot(2,3,5) 表示在 兩行三列的窗口上在第4個位置上,添加一個子窗口 。 窗口的序號是從1開始的
1 import cv2 2 import matplotlib.pyplot as plt 3 img = cv2.imread("/home/miao/dog.jpg" , cv2.IMREAD_GRAYSCALE) 4 equ = cv2.equalizeHist(img) 5 plt.figure("subplot") 6 plt.subplot(121) , plt.hist(img.ravel() , 256) 7 plt.subplot(122) , plt.hist(equ.ravel() , 256) 8 plt.show()
matplotlib.pyplot.imshow( X , cmap = None )
X為圖像信息,可以是各種形式的值
cmap表示色彩空間,默認為None , 默認使用RGB(A)色彩空間
1 import cv2 2 import matplotlib.pyplot as plt 3 import pylab 4 img = cv2.imread("/home/miao/dog.jpg") 5 imgRGB = cv2.cvtColor(img , cv2.COLOR_BGR2RGB) 6 plt.figure("顯示結果") 7 plt.subplot(121) 8 plt.imshow(img) , plt.axis('off') 9 plt.subplot(122) 10 plt.imshow(imgRGB) , plt.axis('off') 11 pylab.show()
plt.axis('off')是關閉坐標軸的顯示
可以看到左側直接使用默認參數色彩空間模式顯示是不正常的,因為圖像讀取時時按BGR通道讀取的,
而該函數時按RGB通道顯示的, 需要通過函數改變通道順序 則可以正常顯示。
沒有pylab模塊是不會顯示的,具體原因,還未查找