opencvfw 2019-06-28
Histograms - 1 : Find, Plot, Analyze !!!
可以将直方图视为图形或绘图,它可以从中全面了解图像的强度分布. 它是在X轴上具有像素值(范围从0到255,并非总是)的图和在Y轴上的图像中的对应像素数.
BINS:像素值区间的像素数.例如将整个直方图分成16个子部分,每个子部分的值是其中所有像素数的总和,每个子部分称为“BIN”.
DIMS:收集数据的参数数量,在这种情况下,我们只收集有关一件事,强度值的数据,所以这里是1.
RANGE :要测量的强度值范围.通常,它是[0,256],即所有强度值.
cv.calcHist(images,channels,mask,histSize,ranges [,hist [,accumulate]])
代码:
import cv2 import numpy as np img = cv2.imread('img.jpg') hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist是256x1数组,每个值对应于该图像中具有相应像素值的像素数
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倍)
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()