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


目录

一、灰度直方图概念

二、直接调用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、结果

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