使用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)

运行结果:

上述分别绘制了灰度图的直方图、彩色图的直方图及带有掩码图像的直方图。

查看原文