目标
学会
使用OpenCV和Numpy函数来查找直方图
图柱直方图,使用OpenCV和Matplotlib函数
您将看到这些功能:cv.calcHist()、np.histogram() 等。
理论
那么什么是直方图呢?你可以把直方图看作是一个图形或图,它能让你对图像的强度分布有一个总体的概念。它是一个带有像素值的图(从0到255,不总是)在x轴上,在y轴上的图像中对应的像素数量。
这只是理解图像的另一种方式。通过观察图像的直方图,你可以直观地了解图像的对比度、亮度、强度分布等。现在几乎所有的图像处理工具都提供了直方图的特性。下面是来自剑桥的彩色网站的图片,我建议你访问这个网站了解更多细节。
img = cv.imread('home.jpg',0)
hist = cv.calcHist([img],[0],None,[256],[0,256])
hist是一个256x1数组,每个值对应于该图像中像素的数量及其对应的像素值。
2。直方图计算Numpy
Numpy还提供了一个函数,np.histogram()。因此,除了cv.calcHist()函数,您可以尝试以下行;
hist,bins = np.histogram(img.ravel(),256,[0,256])
hist和我们之前计算的一样。但是垃圾箱会有257个元素,因为Numpy计算的箱子是0。99,1-1.99,2-2.99等等,所以最终的范围是255-255.99。为了表示这一点,他们还在垃圾箱的末端增加了256个。但我们不需要256。到255就足够了。
另请参阅
Numpy还有另一个函数np.bincount(),它比(大约10倍)np.直方图()要快得多。所以对于一维直方图,你可以试一下。不要忘记在np.bincount中设置minlength=256。例如,hist=np.bincount(img.ravel(),minlength=256)
请注意
OpenCV函数比(大约40X)快于np.histogram()。所以要坚持OpenCV的功能。
现在我们应该画出直方图,但是怎么做呢?
绘制柱状图
有两种方法,
短道:使用Matplotlib绘图函数
长路:使用OpenCV绘图功能
1。使用Matplotlib
Matplotlib附带一个直方图绘制函数 :matplotlib.pyplot.hist()
它直接找到直方图并绘制出来。您不需要使用 calcHist()或 np.histogram() 函数来找到直方图。看下面的代码 :
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('tiananmen.jpg',0)
cv.imshow('image',img)
plt.hist(img.ravel(),256,[0,256]);
plt.show()
cv.waitKey(0)
cv.destoryAllWindows()
或者你可以使用正常的matplotlib图,这对BGR的情节很有帮助。为此,您需要首先找到直方图数据。试试下面的代码:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('tiananmen.jpg')
color = ('b','g','r')
for i,col in enumerate(color):
histr = cv.calcHist([img],[i],None,[256],[0,256])
plt.plot(histr,color = col)
plt.xlim([0,256])
plt.show()
、
你可以从上面的图中扣除,蓝色在图像中有一些高值区域(显然应该是由天空引起的)
2。使用OpenCV
在这里,你调整柱状图的值和它的箱子值,使它看起来像x,y坐标,这样你就可以用cv.line()或cv.polyline()函数来绘制它,以生成上面的相同图像。这已经可以用OpenCV-Python2官方样品了。检查samples/pyth/hist.py的代码。
面具的应用
我们使用cv.calcHist()来找到完整图像的直方图。如果你想要找到图像的某些区域的直方图呢?只要在该区域创建一个白色的蒙版图像,你就可以找到直方图和黑色。然后把这个当作面具。