内容来自OpenCV-Python Tutorials 自己翻译整理
目标:
使用opencv或numpy或Matplotlib函数绘制直方图
学习函数cv2.calcHist(),np.histogram()
原理:
通过直方图可以对图像灰度分布有一个整体了解,x轴上是灰度值(0到255),y轴是图片中该灰度值的像素点的数目。
通过图像可以对图片对比度、亮度、灰度分布有一个直观的认识,如下图:
直方图左侧区域是暗一点的像素数目,右侧为亮一点的像素数目
统计直方图:
相关术语:
BINS: 在上面的直方图当中,如果像素值是0到255,则需要256个值来显示直方图。但是,如果不需要知道每个像素值的像素数目,值想知道两个像素值之间的像素点数目怎么办?例如,想知道像素值在0到15之间的像素点数目,然后是16到31。。。240到255。可以将256个值分成16份,每份计算综合。每个分成的小组就是一个BIN(箱)。在opencv中使用histSize表示BINS。
DIMS: 数据的参数数目。当前例子当中,对收集到的数据只考虑灰度值,所以该值为1。
RANGE: 灰度值范围,通常是[0,256],也就是灰度所有的取值范围。
使用opencv统计直方图:
使用 cv2.calcHist函数完成
参数如下
cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
以灰度格式加载一副图片,统计直方图
img = cv2.imread('home.jpg',0)
hist = cv2.calcHist([img],[0],None,[256],[0,256])
hist是一个256×1的数组,表示每个灰度值对应像素的个数
使用numpy统计直方图
使用np.histogram()函数
hist,bins = np.histogram(img.ravel(),256,[0,256])
与上面的函数一样,但是bins值是257,因为Numpy的计算方式是最后一个范围是255-255.99
在numpy当中还有函数np.bincount(),运行速度很快。所以以为直方图最好使用该函数,minlength=256。例如,hist=np.bincount(img.ravel() ,minlength=256)
然而,opencv函数比上面的函数要更块,所以尽量使用opencv函数
绘制直方图:
有两种方法绘制
1.简短方案,使用Matplotlib绘制
2.长远方案,使用opencv绘制
Matplotlib版本:
使用函数matplotlib.pyplot.hist(),该函数可以直接统计绘制中方图。统计函数为calcHist() 或 np.histogram()
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('10.jpg',0)
plt.hist(img.ravel(),256,[0,256]);
plt.show()
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('12.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()