opencv python 直方图
Histograms - 1 : Find, Plot, Analyze !!!
理论
可以将直方图视为图形或绘图,它可以从中全面了解图像的强度分布. 它是在X轴上具有像素值(范围从0到255,并非总是)的图和在Y轴上的图像中的对应像素数.
查找直方图
BINS:像素值区间的像素数.例如将整个直方图分成16个子部分,每个子部分的值是其中所有像素数的总和,每个子部分称为“BIN”.
DIMS:收集数据的参数数量,在这种情况下,我们只收集有关一件事,强度值的数据,所以这里是1.
RANGE :要测量的强度值范围.通常,它是[0,256],即所有强度值.
1 OpenCV中的直方图计算
cv.calcHist(images,channels,mask,histSize,ranges [,hist [,accumulate]])
- images:它是uint8或float32类型的源图像。它应该用方括号表示,即“[img]”;
- channels:它也在方括号中给出.它是我们计算直方图的通道索引.例如,如果输入是灰度图像,则其值为[0].对于彩色图像,您可以通过[0],[1]或[2]分别计算蓝色,绿色或红色通道的直方图.
- mask:蒙版图像.要查找完整图像的直方图,它将显示为“无”.但是,如果要查找图像特定区域的直方图,则必须为其创建蒙版图像并将其作为蒙版.
- histSize:这代表我们的BIN计数.需要在方括号中给出.对于满量程,我们通过[256].
- ranges:这是我们的范围。通常,它是[0,256].
代码:
import cv2 import numpy as np img = cv2.imread('img.jpg') hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist是256x1数组,每个值对应于该图像中具有相应像素值的像素数
2 Numpy中的直方图计算
hist,bins = np.histogram(img.ravel(),256,[0,256])
hist与我们之前计算的相同. 但是bins将有257个元素,因为Numpy计算bins为0-0.99,1-1.99,2-2.99等.所以最终范围是255-255.99. 为了表示这一点,他们还在箱柜末尾添加256. 但我们不需要256.高达255就足够了.
Numpy还有另一个函数np.bincount()
,它比(大约10倍)np.histogram()
快得多。 因此,对于一维直方图,您可以更好地尝试. 不要忘记在np.bincount
中设置minlength = 256
.
例如,hist = np.bincount(img.ravel(),minlength = 256)
Note:OpenCV函数比np.histogram()快(大约40倍)
绘制直方图
1 使用Matplotlib
Matplotlib附带直方图绘图功能:matplotlib.pyplot.hist()
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('img.jpg',0) plt.hist(img.ravel(),256,[0,256]) plt.show()
原图:
直方图:
或者可以使用matplotlib的正常图,这对BGR图有好处.需要首先找到直方图数据.
代码:
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('img.jpg') color = ('b','g','r') for i,col in enumerate(color): histr = cv2.calcHist([img],[i],None,[256],[0,256]) plt.plot(histr,color = col) plt.xlim([0,256]) plt.show()
掩模的应用
我们使用cv.calcHist()
来查找完整图像的直方图. 如果要查找图像某些区域的直方图, 只需在要查找直方图的区域上创建一个白色的蒙版图像,否则创建黑色. 然后将其作为掩模传递.
代码:
import cv2 import numpy as np from matplotlib import pyplot as plt img = cv2.imread('img.jpg',0) # create a mask mask = np.zeros(img.shape[:2], np.uint8) mask[100:300, 100:400] = 255 masked_img = cv2.bitwise_and(img,img,mask = mask) # Calculate histogram with mask and without mask # Check third argument for mask 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.xlim([0,256]) plt.show()