(一)圖像直方圖
要畫直方圖必須要安裝matplotlib庫,Matplotlib 是一個 Python 的 2D繪圖庫。
圖像直方圖是反映一個圖像像素分布的統計表,其橫坐標代表了圖像像素的種類,可以是灰度的,也可以是彩色的。縱坐標代表了每一種顏色值在圖像中的像素總數或者占所有像素個數的百分比。圖像是由像素構成,因為反映像素分布的直方圖往往可以作為圖像一個很重要的特征。直方圖的顯示方式是左暗又亮,左邊用於描述圖像的暗度,右邊用於描述圖像的亮度
python代碼
import cv2 from matplotlib import pyplot as plt def plot_demo(image): # numpy的ravel函數功能是將多維數組降為一維數組 plt.hist(image.ravel(), 256, [0, 256]) plt.show("直方圖") def image_hist_demo(image): color = {"blue", "green", "red"} # enumerate() 函數用於將一個可遍歷的數據對象(如列表、元組或字符串)組合為一個索引序列,同時列出數據下標和數據,一般用在 for 循環當中。 for i, color in enumerate(color): hist = cv2.calcHist([image], [i], None, [256], [0, 256]) plt.plot(hist, color=color) plt.xlim([0, 256]) plt.show() if __name__ == "__main__": img = cv2.imread("img6.jpg") cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE) cv2.imshow("input image", img) plot_demo(img) image_hist_demo(img) cv2.waitKey(0) cv2.destroyAllWindows()
運行結果:
(二)直方圖應用
直方圖均衡化是圖像處理領域中利用圖像直方圖對對比度進行調整的方法,是圖像增強的一個手段
python代碼
import cv2 __author__ = "boboa" # 全局直方圖均衡化 def equal_hist_demo(image): gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) dst = cv2.equalizeHist(gray) cv2.imshow("equal_hist_demo", dst) # 局部直方圖均衡化 def clahe_demo(image): gray = cv2.cvtColor(image, cv2.COLOR_BGRA2GRAY) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) dst = clahe.apply(gray) cv2.imshow("clahe_demo", dst) if __name__ == "__main__": img = cv2.imread("img7.jpg") cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE) cv2.imshow("input image", img) equal_hist_demo(img) clahe_demo(img) cv2.waitKey(0) cv2.destroyAllWindows()
全局直方圖均衡化運行結果:
局部直方圖均衡化運行結果:
直方圖比較:對輸入的兩張圖像進行直方圖均衡化及直方圖計算步驟后,可以對兩個圖像的直方圖進行對比,並通過對比的結果得到一些我們想要的結論。
python代碼
import cv2 import numpy as np __author__ = "boboa" def create_rgb_hist(image): h, w, c = image.shape rgbHist = np.zeros([16*16*16, 1], np.float32) bsize = 256/16 for row in range(h): for col in range(w): b = image[row, col, 0] g = image[row, col, 1] r = image[row, col, 2] index = np.int(b/bsize)*16*16 + np.int(g/bsize)*16 + np.int(r/bsize) rgbHist[np.int(index), 0] = rgbHist[np.int(index), 0]+1 return rgbHist def hist_compare(image1, image2): hist1 = create_rgb_hist(image1) hist2 = create_rgb_hist(image2) match1 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_BHATTACHARYYA) match2 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CORREL) match3 = cv2.compareHist(hist1, hist2, cv2.HISTCMP_CHISQR) # 巴氏距離越小越相似,相關性越大越相似,卡方越大越不相似 print("巴氏距離", match1) print("相關性", match2) print("卡方", match3) if __name__ == "__main__": img1 = cv2.imread("img5.jpg") img2 = cv2.imread("img6.jpg") cv2.imshow("img1", img1) cv2.imshow("img2", img2) hist_compare(img1, img2) cv2.waitKey(0) cv2.destroyAllWindows()
運行結果
(三)直方圖反向投影
根據樣本的直方圖,找到圖像與樣本相似的地方,即反向投影技術。Opencv中文網站這樣說:所謂反向投影就是首先計算某一特征的直方圖模型,然后使用模型去尋找圖像中存在的該特征。
python代碼
import cv2 from matplotlib import pyplot as plt __author__ = "boboa" def hist2d_demo(image): hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) hist = cv2.calcHist([image], [0, 1], None, [180, 256], [0, 180, 0, 256]) cv2.imshow("hist2d", hist) plt.imshow(hist, interpolation="nearest") plt.title("2d histogram") plt.show() def back_projection_demo(): # 直方圖反向投影 sample = cv2.imread("sample.jpg") target = cv2.imread("target.jpg") roi_hsv = cv2.cvtColor(sample, cv2.COLOR_BGR2HSV) target_hsv = cv2.cvtColor(target, cv2.COLOR_BGR2HSV) cv2.imshow("sample", sample) cv2.imshow("target", target) roihist = cv2.calcHist([roi_hsv], [0, 1], None, [32, 32], [0, 180, 0, 256]) cv2.normalize(roihist, roihist, 0, 255, cv2.NORM_MINMAX) # 歸一化 dst = cv2.calcBackProject(target_hsv, [0, 1], roihist, [0, 180, 0, 256], 1) cv2.imshow("backproject", dst) if __name__ == "__main__": img = cv2.imread("target.jpg") # cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE) # cv2.imshow("input image", img) # hist2d_demo(img) back_projection_demo() cv2.waitKey(0) cv2.destroyAllWindows()
反向投影用於在輸入圖像(通常較大)中查找特定圖像(通常較小或者僅1個像素,以下將其稱為模板圖像)最匹配的點或者區域,也就是定位模板圖像出現在輸入圖像的位置。