Python+OpenCV图像处理之直方图统计

Finn
Finn
发布时间:2026-10-15 | 5人浏览过
原创

本文详细介绍如何使用Python和OpenCV进行图像直方图统计。涵盖直方图基本概念、BINS/DIMS/RANGE术语解析,演示灰度图与彩色通道直方图的绘制方法,讲解利用掩膜提取特定区域直方图的技巧,并深入解析H-S(色调-饱和度)二维直方图的计算与可视化实现。

1. 直方图概述

(1)基本概念

直方图是图像灰度分布的直观表达,它统计了整幅图像中不同灰度级像素的数量。横坐标表示灰度值(范围0至255),纵坐标表示具有该灰度值的像素个数。通过观察直方图,可以直观判断图像的亮度水平、灰度分布情况以及对比度强弱。

(2)直方图中的术语

BINS

在直方图中,横轴代表灰度值。虽然灰度图像有256个等级,但未必需要将每个等级单独标注。若关注的是特定范围内的灰度分布,可将灰度值划分为若干区间,每个区间称为一个BIN(箱)。所有灰度等级被分组后,每组对应一个BIN。

DIMS

DIMS表示收集图像参数的数量。若仅统计灰度值这一单一参数,则DIMS为1。

RANGE

RANGE指统计灰度值的范围,通常设定为[0, 255]。

2. 直方图绘制

(1)读取图像信息

在计算机视觉开发中,首要步骤是读取并解析图像数据:


"""
Author:XiaoMa
date:2021/10/24
"""
#调用需要的包
import cv2
import matplotlib.pyplot as plt
 
img0 = cv2.imread('E:\From Zhihu\For the desk\cvseven.jpeg')
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)     #转化为灰度图
h, w = img1.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img1)
cv2.waitKey(delay = 0)

获取的图像信息如下:

419 636

(2)绘制直方图

绘制直方图主要调用以下函数:

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

images:输入的原图像。

channels:指定统计的通道。[0]代表灰度图;若输入为彩色图像,该参数可设为[0]、[1]或[2],分别对应B、G、R通道。

mask:掩码图像。若需统计整张图像,此处设为None。

histSize:BIN的数量,即直方图的柱数。

ranges:像素值的统计范围。

accumulate:累计标识,通常可省略不写。

灰度图的直方图


#绘制直方图
hist = cv2.calcHist([img1], [0], None, [256], [0, 255])
plt.plot(hist, color = 'lime', label = '直方图', linestyle = '--')
plt.legend()
plt.savefig('E:\From Zhihu\For the desk\cvseven1.jpeg')
plt.show()

从图中可以看出,亮度较高的像素点占据多数,表明该图像整体亮度较高。

彩色图直方图

读取彩色图像后,可对单一通道进行直方图绘制:


"""
Author:XiaoMa
date:2021/10/24
"""
#调用需要的包
import cv2
import matplotlib.pyplot as plt
 
plt.rcParams['font.family'] = 'SimHei'       #将全局中文字体改为黑体
 
img0 = cv2.imread('E:\From Zhihu\For the desk\cvseven.jpeg')
img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
h, w = img1.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img0)
cv2.waitKey(delay = 0)
 
#绘制直方图
hist = cv2.calcHist([img0], [0], None, [256], [0, 255])
plt.plot(hist, color = 'lime', label = '蓝色通道直方图', linestyle = '--', alpha = 1)
plt.legend()
plt.savefig('E:\From Zhihu\For the desk\cvseven1.jpeg')
plt.show()

上图展示了针对蓝色通道绘制的直方图结果。

3. 掩膜直方图

(1)基本概念

若只需统计图像中特定区域的直方图,可创建一幅掩膜图像:将需要统计的区域设为白色(255),无需统计的区域设为黑色(0),以此构成掩膜。

(2)实现代码

生成掩膜图像的步骤如下:


##得到掩膜图
mask = np.zeros(img0.shape, np.uint8)    #将每一个像素点设置为0,就是黑色
mask[109:309, 212:412] = 255             #选取特定区域设置为白色
img0_1 = cv2.bitwise_and(img0, mask)     #图像与操作得到掩膜图
cv2.namedWindow("W1")
cv2.imshow("W1", img0_1)
cv2.waitKey(delay = 0)

基于掩膜绘制直方图:


#绘制掩膜直方图
##得到掩膜图
mask = np.zeros(img1.shape, np.uint8)    #将每一个像素点设置为0,就是黑色
mask[109:309, 212:412] = 255             #选取特定区域设置为白色
img1_1 = cv2.bitwise_and(img1, mask)     #图像与操作得到掩膜图
cv2.namedWindow("W1")
cv2.imshow("W1", img1_1)
cv2.waitKey(delay = 0)
##绘制掩膜直方图和部分图像直方图
hist1 = cv2.calcHist([img1], [0], mask, [256], [0, 255])         #掩膜图直方图,参数需要修改
hist2 = cv2.calcHist([img1], [0], None, [256], [0,255])
plt.plot(hist1, color = 'b', label = '掩膜直方图', linestyle = '--')
plt.plot(hist2, color = 'r', label = '原图直方图', linestyle = '-.')
plt.legend()
plt.savefig('E:\From Zhihu\For the desk\cvseven2.jpeg')
plt.show()

最终得到的图像效果如下:

4. H-S 直方图

(1)基本概念

H-S直方图即色调(Hue)-饱和度(Saturation)直方图。

绘制该直方图需先将源RGB图像转换至HSV(色调、饱和度、亮度)颜色空间。


img0_2 = cv2.cvtColor(img0, cv2.COLOR_BGR2HSV) #将 RGB 空间转化为 HSV 空间
cv2.namedWindow("W2")
cv2.imshow("W2", img0_2)
cv2.waitKey(delay = 0)

(2)绘制二维H-S直方图

此处参考OpenCV官方文档示例。


##绘制H-S直方图
hist3 = cv2.calcHist ([img0_2], [0, 1], None , [180, 256], [0, 180, 0, 256])#官网给出的解释:channel = [0,1] 因为我们需要同时处理 H 和 S 平面;bins = [180,256] H 平面为 180,S 平面为 256;range = [0,180,0,256] 色调值介于 0 和 180 之间,饱和度介于 0 和 256 之间
plt.imshow(hist3)
plt.savefig('E:\From Zhihu\For the desk\cvseven3.jpeg')
plt.show()

得到的图像如下:

图中X轴代表饱和度S,Y轴代表色调H。

该图峰值主要分布在S为0至50、H为20至80的区间。峰值较少的原因可能是原图色彩变化不明显,导致无法形成过多或显著的峰值。

到此这篇关于Python+OpenCV图像处理之直方图统计的文章就介绍到这了,更多相关Python OpenCV直方图统计内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表