使用Matplotlib库和OpenCV库绘制直方图,用到了plt.hist()函数与cv.calcHist()函数。
分别绘制了灰度图的直方图、彩色图的直方图及带有掩码图像的直方图。
代码如下:
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
# 绘制灰度图像直方图
def draw_gray_histogram(img_gray):
# 将图像转换为rgb格式
img_rgb = cv.cvtColor(img_gray, cv.COLOR_BGR2RGB)
'''
plt.hist()参数:
x: 作直方图所要用的数据,必须是一维数组;多维数组可以先进行扁平化再作图;必选参数;
bins: 直方图的柱数,即要分的组数,默认为10;
range:元组(tuple)或None;剔除较大和较小的离群值,给出全局范围;如果为None,则默认为(x.min(), x.max());即x轴的范围;
python 中的 ravel() 函数将数组多维度拉成一维数组。
'''
print(img_gray.ravel())
plt.subplot(121)
plt.imshow(img_rgb)
plt.subplot(122)
plt.hist(img_gray.ravel(), 256, [0, 255])
plt.show()
# 绘制彩色图像直方图
def draw_color_histogram(img_color):
color_bgr = ('b', 'g', 'r')
plt.subplot(121)
plt.imshow(img_color)
for i, j in enumerate(color_bgr):
'''
cv.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) ->hist
images(输入图像):参数必须用方括号括起来。
channels:计算直方图的通道。
Mask(掩膜):一般用None,表示处理整幅图像。
histSize:表示这个直方图分成多少份(即多少个直方柱)。
range:直方图中各个像素的值,[0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。
'''
hist = cv.calcHist([img_color], [i], None, [256], [0, 256])
plt.subplot(122)
plt.plot(hist, color=j)
plt.show()
# 带有掩码图像的直方图
def draw_hasmask_histogram(img_tomask):
# 创造挡板
mask = np.zeros(img_tomask.shape[:2], np.uint8)
mask[60:160, 60:160] = 1
# 与操作
img_has_mask = cv.bitwise_and(img_tomask, img_tomask, mask=mask)
# 计算原图和掩码区域的直方图
hist_O = cv.calcHist([img_tomask], [0], None, [256], [0, 256])
hist_M = cv.calcHist([img_tomask], [0], mask, [256], [0, 256])
plt.subplot(121)
plt.imshow(img_tomask)
plt.subplot(122)
plt.plot(hist_O)
plt.show()
plt.subplot(121)
plt.imshow(img_has_mask)
plt.subplot(122)
plt.plot(hist_M)
plt.show()
if __name__ == '__main__':
img = cv.imread("./image/fengjing.jpg")
draw_gray_histogram(img)
draw_color_histogram(img)
draw_hasmask_histogram(img)
运行结果:
上述分别绘制了灰度图的直方图、彩色图的直方图及带有掩码图像的直方图。