本篇文章介紹如何用OpenCV Python來(lái)計(jì)算直方圖,并簡(jiǎn)略介紹用NumPy和Matplotlib計(jì)算和繪制直方圖
直方圖的背景知識(shí)、用途什么的就直接略過(guò)去了。這里直接介紹方法。
計(jì)算并顯示直方圖
與C++中一樣,在Python中調(diào)用的OpenCV直方圖計(jì)算函數(shù)為cv2.calcHist。
cv2.calcHist的原型為:
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) #返回hist
通過(guò)一個(gè)例子來(lái)了解其中的各個(gè)參數(shù):
#coding=utf-8 import cv2 import numpy as np image = cv2.imread("D:/histTest.jpg", 0) hist = cv2.calcHist([image], [0], #使用的通道 None, #沒(méi)有使用mask [256], #HistSize [0.0,255.0]) #直方圖柱的范圍 其中第一個(gè)參數(shù)必須用方括號(hào)括起來(lái)。
第二個(gè)參數(shù)是用于計(jì)算直方圖的通道,這里使用灰度圖計(jì)算直方圖,所以就直接使用第一個(gè)通道;
第三個(gè)參數(shù)是Mask,這里沒(méi)有使用,所以用None。
第四個(gè)參數(shù)是histSize,表示這個(gè)直方圖分成多少份(即多少個(gè)直方柱)。第二個(gè)例子將繪出直方圖,到時(shí)候會(huì)清楚一點(diǎn)。
第五個(gè)參數(shù)是表示直方圖中各個(gè)像素的值,[0.0, 256.0]表示直方圖能表示像素值從0.0到256的像素。
最后是兩個(gè)可選參數(shù),由于直方圖作為函數(shù)結(jié)果返回了,所以第六個(gè)hist就沒(méi)有意義了(待確定)
最后一個(gè)accumulate是一個(gè)布爾值,用來(lái)表示直方圖是否疊加。
彩色圖像不同通道的直方圖
下面來(lái)看下彩色圖像的直方圖處理。以最著名的lena.jpg為例,首先讀取并分離各通道:
import cv2 import numpy as np img = cv2.imread("D:/lena.jpg") b, g, r = cv2.split(img) 接著計(jì)算每個(gè)通道的直方圖,這里將其封裝成一個(gè)函數(shù):
def calcAndDrawHist(image, color): hist= cv2.calcHist([image], [0], None, [256], [0.0,255.0]) minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist) histImg = np.zeros([256,256,3], np.uint8) hpt = int(0.9* 256); for h in range(256): intensity = int(hist[h]*hpt/maxVal) cv2.line(histImg,(h,256), (h,256-intensity), color) return histImg;
這里只是之前代碼的簡(jiǎn)單封裝,所以注釋就省掉了。
接著在主函數(shù)中使用:
if __name__ == '__main__': img = cv2.imread("D:/lena.jpg") b, g, r = cv2.split(img) histImgB = calcAndDrawHist(b, [255, 0, 0]) histImgG = calcAndDrawHist(g, [0, 255, 0]) histImgR = calcAndDrawHist(r, [0, 0, 255]) cv2.imshow("histImgB", histImgB) cv2.imshow("histImgG", histImgG) cv2.imshow("histImgR", histImgR) cv2.imshow("Img", img) cv2.waitKey(0) cv2.destroyAllWindows() 這樣就能得到三個(gè)通道的直方圖了,如下:
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注