Python版本是Python3.7.3,OpenCV版本OpenCV3.4.1,开发环境为PyCharm

13.3 使用OpenCV绘制直方图

OpenCV提供了函数cv2.calcHist()用来计算图像的统计直方图,该函数能统计各个灰度级的像素点个数。利用matplotlib.pyplot模块中的plot()函数,可以将函数cv2.calcHist()的统计结果绘制成直方图。

1.用cv2.calcHist()函数统计图像直方图信息
函数cv2.calcHist()用于统计图像直方图信息,其语法格式为:

hist = cv2.calcHist( images, channels, mask, histSize, ranges, accumulate )

函数中返回值及参数的含义为:
● hist:返回的统计直方图,是一个一维数组,数组内的元素是各个灰度级的像素个数。
● images:原始图像,该图像需要使用“[ ]”括起来。
● channels:指定通道编号。通道编号需要用“[ ]”括起来,如果输入图像是单通道灰度图像,该参数的值就是[0]。对于彩色图像,它的值可以是[0]、[1]、[2],分别对应通道B、G、R。
● mask:掩模图像。当统计整幅图像的直方图时,将这个值设为None。当统计图像某一部分的直方图时,需要用到掩模图像。
● histSize:BINS的值,该值需要用“[ ]”括起来。例如,BINS的值是256,需要使用“[256]”作为此参数值。
● ranges:即像素值范围。例如,8位灰度图像的像素值范围是[0, 255]。
● accumulate:累计(累积、叠加)标识,默认值为False。如果被设置为True,则直方图在开始计算时不会被清零,计算的是多个直方图的累积结果,用于对一组图像计算直方图。该参数允许从多个对象中计算单个直方图,或者实时更新直方图。该参数是可选的,一般情况下不需要设置。

eg1:使用cv2.calcHist()函数计算一幅图像的统计直方图结果,并观察得到的统计直方图信息。
根据题目的要求,编写代码如下:

import cv2
img=cv2.imread("image\\lena.bmp")
hist = cv2.calcHist([img],[0],None,[256],[0,255])
print(type(hist))
print(hist.shape)
print(hist.size)
print(hist)

需要注意,在本例的cv2.calcHist()函数中:

● 第1个参数“[img]”表示要绘制直方图的原始图像,是使用“[ ]”括起来的。

● 第2个参数表示要统计哪个通道的直方图信息。本例中读取的img是灰度图像,所以使用“[0]”来表示。

● 第3个参数是掩模图像,在本例中的值为“None”,表示计算整幅图像的直方图。

● 第4个参数“[256]”表示BINS的值是256。

● 第5个参数“[0, 255]”表示灰度级的范围是[0, 255]。

程序运行结果如下图所示。

python qt 直方图 python绘制直方图的函数_图像处理

从图中可以看到,函数cv2.calcHist()返回值的数据类型为“ndarray”。该数据的shape为(256,1),说明其有256行1列。该数据的size为256,说明有256个元素,分别对应着256个灰度级在图像内出现的次数。
图中所示的程序运行结果的下半部分是hist内的部分数据,限于篇幅,这里仅截取了256条数据中的前6条。这6条数据,对应着灰度级为0~5的像素点出现的次数。

2.plot()函数的使用
使用matplotlib.pyplot模块内的plot()函数,可以将函数cv2.calcHist()的返回值绘制为图像直方图。下面通过三个例子来学习plot()函数的基本使用方法。

eg2:将给定的x= [0,1,2,3,4,5,6], y = [0.3,0.4,2,5,3,4.5,4],使用plot()函数绘制出来。
根据题目的要求,编写代码如下:

import matplotlib.pyplot as plt
x = [0,1,2,3,4,5,6]
y = [0.3,0.4,2,5,3,4.5,4]
plt.plot(x,y)
plt.show(  )   # 显示图像

程序的运行结果如下图所示。图中x轴由x= [0, 1, 2, 3, 4, 5, 6]指定,y轴由y= [0.3, 0.4, 2, 5, 3, 4.5, 4]指定。

python qt 直方图 python绘制直方图的函数_图像处理_02

eg3:给定y = [0.3, 0.4, 2, 5, 3, 4.5, 4],使用plot()函数将其绘制出来,观察绘制结果。
:如下代码:

import matplotlib.pyplot as plt
y = [0.3,0.4,2,5,3,4.5,4]
plt.plot(y)
plt.show(  )   # 显示图像

执行上述程序,运行结果如下图所示。从图中可以看出,在使用plot()函数时,如果仅仅指定一个参数,则其对应x轴的值默认是一个自然数序列x=[0, 1, … , n-1, n]。自然序列x的长度与y的长度保持一致。

python qt 直方图 python绘制直方图的函数_Python-OpenCV_03

eg4:使用plot()函数将两组不同的值a= [0.3, 0.4, 2, 5, 3, 4.5, 4], b=[3, 5, 1, 2, 1, 5, 3]以不同的颜色绘制出来。
代码如下:

import matplotlib.pyplot as plt
a = [0.3,0.4,2,5,3,4.5,4]
b=[3,5,1,2,1,5,3]
plt.plot(a,color='r')
plt.plot(b,color='g')
plt.show(  )   # 显示图像

上述代码中:
● color='r’表示绘图曲线的color属性是“red”,即绘图颜色是红色的。
● color='g’表示绘图曲线的color属性是“green”,即绘图颜色是绿色的。
在绘图时,可以根据需要将color属性设置为不同颜色。执行上述程序,绘图结果如下图所示。

python qt 直方图 python绘制直方图的函数_使用OpenCV绘制直方图_04

3.绘制统计直方图
熟悉函数plot()的使用后,就可以使用它将函数cv2.calcHist()的返回值绘制为直方图了。

eg5:使用函数plot()将函数cv2.calcHist()的返回值绘制为直方图。
代码如下:

import cv2
import matplotlib.pyplot as plt
o=cv2.imread("image\\boatGray.bmp")
histb = cv2.calcHist([o],[0],None,[256],[0,255])
plt.plot(histb,color='b')
plt.show()
plt.show(  )   # 显示图像

运行上述程序,得到如下图所示直方图。

python qt 直方图 python绘制直方图的函数_python qt 直方图_05

本例首先通过函数cv2.calcHist()得到图像的统计直方图数据,然后利用函数plot()将这些数据绘制出来。

eg6:使用函数plot()和函数cv2.calcHist(),将彩色图像各个通道的直方图绘制在一个窗口内。

代码如下:

import cv2
import matplotlib.pyplot as plt
o=cv2.imread("image\\girl.bmp")
histb = cv2.calcHist([o],[0],None,[256],[0,255])
histg = cv2.calcHist([o],[1],None,[256],[0,255])
histr = cv2.calcHist([o],[2],None,[256],[0,255])
plt.plot(histb,color='b')
plt.plot(histg,color='g')
plt.plot(histr,color='r')
plt.show()

运行上述程序,得到如下图所示直方图。

python qt 直方图 python绘制直方图的函数_使用OpenCV绘制直方图_06

本例先通过函数cv2.calcHist()分别得到[0]、[1]、[2]三个通道(即B、G、R三个通道)的统计直方图数据,然后再通过plot()函数将这些数据绘制成直方图。