圖像灰度直方圖
圖像是由像素點構成的,每個像素點的值代表着該點的顏色(灰度圖或者彩色圖)。
直方圖就是對圖像中的這些像素點的值進行統計,得到一個統一的整體的灰度概念。
優點:可以清晰了解圖像的整體灰度分布,對於后面依據直方圖處理圖像來說至關重要。
一般情況下直方圖都是灰度圖像,直方圖x軸是灰度值(一般0~255),y軸是圖像中每一個灰度級對應的像素點的個數。
灰度級:正常情況下就是0-255共256個灰度級,從黑一直到白(也有可能統計其中的某部分灰度范圍),那么每一個灰度級對應一個數值代表該灰度對應的點數目。
也就是說直方圖其實就是一個1*m(灰度級)的一個數組而已。但是有的時候不希望逐個灰度的遞增,比如現在要求20個灰度一起作為一個灰度級來畫直方圖,這個時候
可能只需要1*(m/20)這樣一個數組就夠了。那么這里的20就是直方圖的間隔寬度了。
Opencv給提供的函數是cv2.calcHist(),該函數有5個參數:
- image輸入圖像,傳入時應該用中括號[]括起來
- channels::傳入圖像的通道,如果是灰度圖像,那就不用說了,只有一個通道,值為0,如果是彩色圖像(有3個通道),那么值為0,1,2,中選擇一個,對應着BGR各個通道,用[]傳入。
- mask:掩膜圖像。如果統計整幅圖,那么為none。如果要統計部分圖的直方圖,就得構造相應的炎掩膜來計算。
- histSize:灰度級的個數,需要中括號,比如[256]
- ranges:像素值的范圍,通常[0,256],有的圖像如果不是0-256,比如說你來回各種變換導致像素值負值、很大,則需要調整后才可以。
除Opencv外,numpy也有函數用於統計直方圖的
函數np.histogram()
函數np.bincount()
這三個方式的傳入參數基本上差不多,不同的是opencv自帶的需要中括號括起來。
測試案例:
import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('02.jpg', 0)#直接讀為灰度圖像 #opencv讀取方法cv2.calcHist(速度最快) #圖像,通道[0]-灰度圖,掩膜-無,灰度級,像素范圍 hist_cv = cv2.calcHist([img], [0], None, [256], [0,256]) #numpy方法讀取np.histogram() hist_np,bins = np.histogram(img.ravel(), 256, [0,256]) #numpy的另一種讀取方法np.bincount()(速度=10倍方法2) hist_np2 = np.bincount(img.ravel(), minlength=256) plt.subplot(221), plt.imshow(img, 'gray') plt.subplot(222), plt.plot(range(256), hist_cv, 'r') plt.subplot(223), plt.plot(range(256), hist_np, 'b') plt.subplot(224), plt.plot(hist_np2) plt.show()
opencv的直方圖函數中掩膜的使用,這個掩膜就是一個區域大小,表示直方圖統計就是這個區域的像素統計。
掩膜是用一副二值化圖片對另外一幅圖片進行局部的遮擋
import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('02.jpg', 0)#直接讀為灰度圖像 #生成掩膜 mask = np.zeros(img.shape[:2], np.uint8) mask[200:400, 300:500] = 255 #Cv2.bitwise_and (目標文件,源文件,mask),將圖片里的像素值按位與 masked_img = cv2.bitwise_and(img, img, mask=mask) #opencv讀取方法cv2.calcHist(速度最快) #圖像,通道[0]-灰度圖,掩膜-無,灰度級,像素范圍 hist_full = cv2.calcHist([img], [0], None, [256], [0,256]) hist_mask = cv2.calcHist([img], [0], mask, [256], [0,256]) plt.subplot(221), plt.imshow(img, 'gray') plt.subplot(222), plt.imshow(mask, 'gray') plt.subplot(223), plt.imshow(masked_img, 'gray') plt.subplot(224), plt.plot(hist_full),plt.plot(hist_mask) plt.show()
import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread('02.jpg', 0)#直接讀為灰度圖像 #生成掩膜 mask = np.zeros(img.shape[:2], np.uint8) mask[200:400, 300:500] = 255 #Cv2.bitwise_and (目標文件,源文件,mask),將圖片里的像素值按位與 masked_img = cv2.bitwise_and(img, img, mask=mask) #opencv讀取方法cv2.calcHist(速度最快) #圖像,通道[0]-灰度圖,掩膜-無,灰度級,像素范圍 hist_full = cv2.calcHist([img], [0], None, [256], [0,256]) hist_mask = cv2.calcHist([img], [0], mask, [256], [0,256]) plt.subplot(221), plt.imshow(img, 'gray') plt.subplot(222), plt.imshow(mask, 'gray') plt.subplot(223), plt.imshow(masked_img, 'gray') plt.subplot(224), plt.plot(hist_full),plt.plot(hist_mask) plt.show()