目录
一、灰度直方图概念
二、直接调用opencv的函数caclHist()
1、函数介绍
2、实例
三、自定义函数进行灰度直方图的绘制
1、代码
2、结果
一、灰度直方图概念
灰度直方图是关于灰度级分布的函数,将数字图像中的所有像素,按照灰度值的大小,统计其出现的频率。其中,横坐标是灰度级,纵坐标是该灰度级出现的频率。
对图像中不同灰度级别出现的次数进行统计,统计后进行绘制直方图,横坐标表示灰度级别0-255,纵坐标表示每个灰度级别在图像中出现的次数,一般会对次数进行归一化,用每个灰度级出现的次数除以图像的像素总个数。
二、直接调用opencv的函数caclHist()
1、函数介绍
返回的是一个一维数组(256,1)
1 | hist = cv2.calcHist(images,channels,mask,histSize,ranges [,hist [,accumulate]]) |
1 2 3 4 5 6 | 参数说明: images:uint8或float32类型的原图像。用方括号表示,即“[img]”; channels:计算直方图的通道索引,也在方括号中给出.例如,如果输入是灰度图像,则其值为[0].对于彩色图像,可以通过[0],[1]或[2]分别计算蓝色,绿色或红色通道的直方图. mask:掩码,蒙版图像.要查找完整图像的直方图,它将显示为“无”.但是,如果要查找图像特定区域的直方图,则必须为其创建蒙版图像并将其作为蒙版. histSize:这代表我们的BIN计数.需要在方括号中给出.对于满量程,我们通过[256]. ranges:这是我们的范围。通常,它是[0,256]. |
2、实例
获得上图的直方图,首先得先进行灰度化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import cv2 import numpy as np import matplotlib.pyplot as plt def image_calcuhist(imagepath): img = cv2.imread(imagepath)#读取图片 img_shape = img.shape gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#灰度化 hist = cv2.calcHist([gray],[0],None,[256],[0,256])#计算灰度级别出现频率,返回的是一个(256,1)的数组 for i in range(hist.shape[0]): hist[i] = hist[i]/(img_shape[0]*img_shape[1])#对获得的直方图数据进行归一化 return hist if __name__ == '__main__': x = np.linspace(0,255,256)#横坐标灰度级别 y = image_calcuhist("colorful_lena.jpg")#纵坐标值获取 plt.bar(x,y.ravel(),0.9,alpha=1,color='b')#通过matplotlib进行直方图的绘制 plt.show()#显示直方图 |
三、自定义函数进行灰度直方图的绘制
1、代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # 1 0-255 2 概率 # 本质:统计每个像素灰度 出现的概率 0-255 p import cv2 import numpy as np import matplotlib.pyplot as plt def image_histdefinition(imagepath): img = cv2.imread(imagepath)#读取图片 imgInfo = img.shape#获得图片的尺寸大小 height = imgInfo[0] width = imgInfo[1] # 灰度化 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) count = np.zeros(256,np.float) # 共256个,创建一个数组用于存放灰度级别出现的频率 #计算灰度级别频率 for i in range(0,height): for j in range(0,width): pixel = gray[i,j] # 获取灰度等级 index = int(pixel) # 强制类型转换 count[index] = count[index]+1 # 计算出现概率,即归一化 for i in range(0,255): count[i] = count[i]/(height*width) return count if __name__ == '__main__': # 绘图 x = np.linspace(0, 255, 256) count = image_histdefinition('colorful_lena.jpg') y = count plt.bar(x, y, 0.9, alpha=1, color='b') plt.show() |
2、结果
两种方法得到的直方图是一样的,证明方法是可行的。