【图像处理】——图像灰度直方图的绘制(直接调用函数和自定义函数)

    技术2023-05-29  34

    目录

    一、灰度直方图概念

    二、直接调用opencv的函数caclHist()

    1、函数介绍

    2、实例

    (1)绘制全局直方图

    (2)绘制局部的直方图

    三、自定义函数进行灰度直方图的绘制

    1、代码

    2、结果


     


    一、灰度直方图概念

    灰度直方图是关于灰度级分布的函数,将数字图像中的所有像素,按照灰度值的大小,统计其出现的频率。其中,横坐标是灰度级,纵坐标是该灰度级出现的频率。

    对图像中不同灰度级别出现的次数进行统计,统计后进行绘制直方图,横坐标表示灰度级别0-255,纵坐标表示每个灰度级别在图像中出现的次数,一般会对次数进行归一化,用每个灰度级出现的次数除以图像的像素总个数。

    二、直接调用opencv的函数caclHist()

    1、函数介绍

    返回的是一个一维数组(256,1)

    hist = cv2.calcHist([images],[channels],mask,histSize,ranges ) 参数说明: images:uint8或float32类型的原图像。用方括号表示,即“[img]”; channels:计算直方图的通道索引,也在方括号中给出.例如,如果输入是灰度图像,则其值为[0].对于彩色图像,可以通过[0],[1]或[2]分别计算蓝色,绿色或红色通道的直方图. mask:掩码,蒙版图像.要查找完整图像的直方图,它将显示为“无”.但是,如果要查找图像特定区域的直方图,则必须为其创建蒙版图像并将其作为蒙版. histSize:灰度级的个数,这代表我们的BIN计数.需要在方括号中给出.对于满量程,我们通过[256]. ranges:这是像素值的范围的范围。通常,它是[0,256].

    2、实例

    (1)绘制全局直方图

    获得上图的直方图,首先得先进行灰度化

    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()#显示直方图

    (2)绘制局部的直方图

    import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread("colorful_lena.jpg",0) h,w = img.shape #构建一个掩模,需要绘制直方图的局部图像区域的像素设置为255,其他部分设置为0 mask = np.zeros((h,w),np.uint8) for i in range(0,int(h/2)): for j in range(0,int(w/2)): mask[int(h/4)+i,int(w/4)+j] = 255 #全幅图像的直方图 hist = cv2.calcHist([img],[0],None,[256],[0,256]) #局部的直方图 hist1 = cv2.calcHist([img],[0],mask,[256],[0,256]) x = np.linspace(0,255,256) plt.plot(x,hist.ravel()) plt.plot(x,hist1.ravel()) plt.show() cv2.imshow('',mask) cv2.imshow('1',img) cv2.waitKey(0)

    蓝色线为全局直方图,橙色为局部直方图

    三、自定义函数进行灰度直方图的绘制

    1、代码

    # 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、结果

     

    两种方法得到的直方图是一样的,证明方法是可行的。

    Processed: 0.017, SQL: 8