直方圖簡介:圖像的直方圖是用來表現圖像中亮度分佈的直方圖,給出的是圖像中某個亮度或者某個範圍亮度下共有幾個像素.還不明白?就是統計一幅圖某個亮度像素數量.好比對於灰度值12,一幅圖裏面有2000 個像素其灰度值爲12,那麼就可以統計12這個亮度的像素爲2000個,其餘類推。參考:https://blog.csdn.net/xierhacker/article/details/52605308python
1、安裝matplotlib算法
要畫直方圖必需要安裝matplotlib庫,Matplotlib 是一個 Python 的 2D繪圖庫。數組
安裝步驟:app
運行cmd,而後在本身的python安裝路徑的Scripts文件夾目錄下,輸入命令: pip install matplotlib函數
2、畫直方圖ui
代碼以下:spa
#畫直方圖 import cv2 as cv from matplotlib import pyplot as plt def plot_demo(image): plt.hist(image.ravel(), 256, [0, 256]) #numpy的ravel函數功能是將多維數組降爲一維數組 plt.show() def image_hist(image): #畫三通道圖像的直方圖 color = ('b', 'g', 'r') #這裏畫筆顏色的值能夠爲大寫或小寫或只寫首字母或大小寫混合 for i , color in enumerate(color): hist = cv.calcHist([image], [i], None, [256], [0, 256]) #計算直方圖 plt.plot(hist, color) plt.xlim([0, 256]) plt.show() src = cv.imread('E:/imageload/WindowsLogo.jpg') cv.namedWindow('input_image', cv.WINDOW_NORMAL) cv.imshow('input_image', src) plot_demo(src) image_hist(src) cv.waitKey(0) cv.destroyAllWindows()
運行結果:.net
注意:3d
1.numpy的ravel函數功能是將多維數組降爲一維數組。參考博客:http://www.javashuo.com/article/p-qbcdgzmc-gg.htmlcode
2.matplotlib.pyplot.hist函數主要是計算直方圖。
hist函數原型:hist(x, bins=None, range=None, density=None, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, normed=None, hold=None, data=None, **kwargs)
x參數表示是一個數組或一個序列,是指定每一個bin(箱子)分佈的數據
bins參數表示指定bin(箱子)的個數,也就是總共有幾條條狀圖
range參數表示箱子的下限和上限。即橫座標顯示的範圍,範圍以外的將被捨棄。
參考博客:https://blog.csdn.net/u013571243/article/details/48998619
3.enumerate() 函數用於將一個可遍歷的數據對象(如列表、元組或字符串)組合爲一個索引序列,同時列出數據下標和數據,通常用在 for 循環當中。
4.cv2.calcHist的原型爲:calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) -> hist
images參數表示輸入圖像,傳入時應該用中括號[ ]括起來
channels參數表示傳入圖像的通道,若是是灰度圖像,那就不用說了,只有一個通道,值爲0,若是是彩色圖像(有3個通道),那麼值爲0,1,2,中選擇一個,對應着BGR各個通道。這個值也得用[ ]傳入。
mask參數表示掩膜圖像。若是統計整幅圖,那麼爲None。主要是若是要統計部分圖的直方圖,就得構造相應的掩膜來計算。
histSize參數表示灰度級的個數,須要中括號,好比[256]
ranges參數表示像素值的範圍,一般[0,256]。此外,假如channels爲[0,1],ranges爲[0,256,0,180],則表明0通道範圍是0-256,1通道範圍0-180。
hist參數表示計算出來的直方圖。
參考:https://blog.csdn.net/YZXnuaa/article/details/79231817
5.關於pyplot模塊裏plot()函數、xlim()函數等的用法參考:
https://blog.csdn.net/cymy001/article/details/78344316
https://blog.csdn.net/chinwuforwork/article/details/51786967
3、直方圖的應用
代碼以下:
#直方圖的應用 直方圖均衡化(即調整圖像的對比度) 直方圖即統計各像素點的頻次 import cv2 as cv #全局直方圖均衡化 def eaualHist_demo(image): gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) #opencv的直方圖均衡化要基於單通道灰度圖像 cv.namedWindow('input_image', cv.WINDOW_NORMAL) cv.imshow('input_image', gray) dst = cv.equalizeHist(gray) #自動調整圖像對比度,把圖像變得更清晰 cv.namedWindow("eaualHist_demo", cv.WINDOW_NORMAL) cv.imshow("eaualHist_demo", dst) #局部直方圖均衡化 def clahe_demo(image): gray = cv.cvtColor(image, cv.COLOR_RGB2GRAY) clahe = cv.createCLAHE(5, (8,8)) dst = clahe.apply(gray) cv.namedWindow("clahe_demo", cv.WINDOW_NORMAL) cv.imshow("clahe_demo", dst) src = cv.imread('E:/imageload/rice.png') eaualHist_demo(src) clahe_demo(src) cv.waitKey(0) cv.destroyAllWindows()
運行結果:
注意:
1.cv2.equalizeHist函數原型:equalizeHist(src[, dst]) -> dst。函數equalizeHist的做用:直方圖均衡化,提升圖像質量。
2.直方圖均衡化:若是一副圖像的像素佔有不少的灰度級並且分佈均勻,那麼這樣的圖像每每有高對比度和多變的灰度色調。直方圖均衡化就是一種能僅靠輸入圖像直方圖信息自動達到這種效果的變換函數。它的基本思想是對圖像中像素個數多的灰度級進行展寬,而對圖像中像素個數少的灰度進行壓縮,從而擴展像元取值的動態範圍,提升了對比度和灰度色調的變化,使圖像更加清晰。
3.全局直方圖均衡化可能獲得是一種全局意義上的均衡化,可是有的時候這種操做並非很好,會把某些不應調整的部分給調整了。Opencv中還有一種直方圖均衡化,它是一種局部直方圖均衡化,也就是是說把整個圖像分紅許多小塊(好比按10*10做爲一個小塊),那麼對每一個小塊進行均衡化。
4.createCLAHE函數原型:createCLAHE([, clipLimit[, tileGridSize]]) -> retval
clipLimit參數表示對比度的大小。
tileGridSize參數表示每次處理塊的大小 。
5.
clahe = cv.createCLAHE(5, (8,8))
dst = clahe.apply(gray) #猜想:把clahe這種局部直方圖均衡化應用到灰度圖gray
4、直方圖反向投影
代碼以下:
#直方圖反向投影技術(經過二維直方圖反映,必須先把原圖像轉換爲hsv) import cv2 as cv #計算H-S直方圖 def back_projection_demo(): sample = cv.imread("E:/imageload/sample.jpg") target = cv.imread("E:/imageload/target.jpg") roi_hsv = cv.cvtColor(sample, cv.COLOR_BGR2HSV) target_hsv = cv.cvtColor(target, cv.COLOR_BGR2HSV) cv.namedWindow("sample", cv.WINDOW_NORMAL) cv.imshow("sample", sample) cv.namedWindow("target", cv.WINDOW_NORMAL) cv.imshow("target", target) roiHist = cv.calcHist([roi_hsv], [0, 1], None, [32, 30], [0, 180, 0, 256])#計算樣本直方圖 [32, 30]越小,效果越好 cv.normalize(roiHist, roiHist, 0, 255, cv.NORM_MINMAX) #規劃到0-255之間 dst = cv.calcBackProject([target_hsv], [0,1], roiHist, [0, 180, 0, 256], 1) #計算反向投影 cv.namedWindow("back_projection_demo", cv.WINDOW_NORMAL) cv.imshow("back_projection_demo", dst) back_projection_demo() cv.waitKey(0) cv.destroyAllWindows()
運行結果:
注意:
1. 歸一化就是要把須要處理的數據通過處理後(經過某種算法)限制在你須要的必定範圍內。
歸一化函數cv2.normalize原型:normalize(src, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]]) -> dst
src參數表示輸入數組。
dst參數表示輸出與src相同大小的數組,支持原地運算。
alpha參數表示range normalization模式的最小值。
beta參數表示range normalization模式的最大值,不用於norm normalization(範數歸一化)模式。
norm_type參數表示歸一化的類型。
norm_type參數能夠有如下的取值:
NORM_MINMAX:數組的數值被平移或縮放到一個指定的範圍,線性歸一化,通常較經常使用。
NORM_INF:歸一化數組的C-範數(絕對值的最大值)。
NORM_L1 :歸一化數組的L1-範數(絕對值的和)。
NORM_L2 :歸一化數組的(歐幾里德)L2-範數。
參考博客:https://blog.csdn.net/solomon1558/article/details/44689611
2.反向投影用於在輸入圖像(一般較大)中查找特定圖像(一般較小或者僅1個像素,如下將其稱爲模板圖像)最匹配的點或者區域,也就是定位模板圖像出如今輸入圖像的位置。
函數cv2.calcBackProject用來計算直方圖反向投影。
函數原型:calcBackProject(images, channels, hist, ranges, scale[, dst]) -> dst
images參數表示輸入圖像(是HSV圖像)。傳入時應該用中括號[ ]括起來。
channels參數表示用於計算反向投影的通道列表,通道數必須與直方圖維度相匹配。
hist參數表示輸入的模板圖像直方圖。
ranges參數表示直方圖中每一個維度bin的取值範圍 (即每一個維度有多少個bin)。
scale參數表示可選輸出反向投影的比例因子,通常取1。
參考博客:https://blog.csdn.net/keith_bb/article/details/70154219