计算机视觉基础 第 10 章|图像直方图与直方图均衡化

前言

本章主要学习图像直方图的相关知识与实操应用,涵盖直方图基础概念、图像直方图绘制、掩码局部灰度统计以及直方图均衡化图像增强技术,结合代码实战完成图像灰度分析与图像增强任务。

一、核心 API 介绍

1.1 图像直方图基础概念

结合示意图可直观理解:图像直方图是针对图像灰度信息的二维分布统计图,专门用于量化图像明暗结构,完全对应图片对应关系:

横轴(X轴):灰度级别,取值固定为 0~255。其中 0 代表纯黑色、255 代表纯白色,中间数值对应不同亮度的灰色,完整覆盖图像所有明暗等级。

纵轴(Y轴):像素数量,代表当前横坐标对应灰度级别的像素点总个数,用于体现该亮度在整张图像中的占比多少。

从示意图可以明显看出:直方图不记录图像空间信息,不关注物体位置、轮廓、纹理、形状,只统计「不同亮度像素有多少个」的全局数值分布。无论图像中物体如何平移、变换位置,只要灰度像素数量比例不变,直方图曲线就不会改变。

1.2 使用直方图的意义与作用

人眼观察图像只能获得主观视觉感受,无法精准判断图像的明暗分布、对比度强弱,而直方图可以将图像视觉特征数据化、量化,为图像处理提供客观依据。主要作用如下:

  1. 辅助图像分析:通过直方图分布形态,可快速判断图像偏暗、偏亮、对比度过高或过低等问题;

  2. 实现图像增强:基于直方图均衡化算法,重新分布灰度像素,优化图像对比度;

  3. 支持局部统计:结合掩码 Mask,可单独统计图像感兴趣区域(ROI)的灰度分布,实现局部图像分析。

1.3 直方图核心特点

直方图具备位置无关性,只要两张图像的灰度像素数量、分布比例一致,无论图像内容、物体位置如何变化,最终生成的直方图完全一致。

1. cv2.calcHist () 计算图像直方图

|--------------------------------------------|
| 作用:统计图像像素灰度级分布,得到直方图数据,可使用 matplotlib 绘制曲线 |

python 复制代码
cv2.calcHist(images, channels, mask, histSize, ranges)

参数说明:

  1. images:原图像,格式为 uint8,传入需要用\[\]包裹,例如img
  2. channels:要统计的通道索引,灰度图填0;彩色图 BGR 分别对应012
  3. mask:掩码图像。统计整张图像直方图填None;如果只想统计图像部分区域,传入 mask 掩码。mask 等于 0 的区域不参与统计,非 0 区域参与统计。
  4. histSize:BIN 的数量,也就是灰度分组数目,需要\[\]包裹;统计 0‑255 全部灰度,填256
  1. ranges:像素取值范围,灰度图像固定0,256

2. np.ravel()

|----------------------------------------------|
| numpy 函数,把多维的图像数组拉伸为一维数组,配合plt.hist()直接画直方图。 |

3. cv2.bitwise_and () 按位与运算

python 复制代码
cv2.bitwise_and(src1, src2, dst=None, mask=None)
  • src1、src2:参与运算输入图像
  • mask:掩码,掩码为 0 的位置输出全部置 0;非 0 位置正常输出运算结果。

4. cv2.equalizeHist () 直方图均衡化

|----------------------------------------------------|
| 图像增强技术,重新分布图像灰度像素,提升图像对比度、亮度,改善图像视觉效果。 只接收灰度图作为输入。 |

二、绘制灰度图直方图

为直观掌握图像直方图的绘制方法,本节以手机灰度图像为测试样本,分别通过两种方式绘制图像直方图,实现图像灰度分布的可视化统计。

2.1 方式 1:plt.hist + ravel ()

python 复制代码
import cv2
import matplotlib.pyplot as plt

#读取灰度图片
phone = cv2.imread('phone.png',cv2.IMREAD_GRAYSCALE)
#ravel:多维数组转为一维
a = phone.ravel()
#绘制直方图
plt.hist(a,bins=256)
plt.show()

2.2 方式 2:cv2.calcHist 获取直方图数据再绘图

python 复制代码
import cv2
import matplotlib.pyplot as plt

phone = cv2.imread('phone.png',cv2.IMREAD_GRAYSCALE)
#计算直方图数据
phone_hist = cv2.calcHist(images=[phone],channels=[0],mask=None,histSize=[256],ranges=[0,256])
plt.plot(phone_hist)
plt.show()

2.3 彩色图像多通道直方图绘制

分别统计 B、G、R 三个通道的直方图并绘制曲线

python 复制代码
import cv2
import matplotlib.pyplot as plt

img = cv2.imread('phone.png')
color = ('b','g','r')
for i,col in enumerate(color):
    histr = cv2.calcHist(images=[img],channels=[i],mask=None,histSize=[256],ranges=[0,256])
    plt.plot(histr,color=col)
plt.show()

三、mask 掩码,局部图像直方图统计

python 复制代码
import cv2
import matplotlib.pyplot as plt
import numpy as np

phone = cv2.imread('phone.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow('phone',phone)
cv2.waitKey(0)

#创建掩码:全黑图像,指定矩形区域置为白色255
mask = np.zeros(phone.shape[:2],np.uint8)
mask[50:350,100:470] = 255
cv2.imshow('mask',mask)
cv2.waitKey(0)

#bitwise_and 掩码提取ROI区域
phone_mask = cv2.bitwise_and(phone,phone,mask=mask)
cv2.imshow('phone_mask',phone_mask)
cv2.waitKey(0)

#只统计mask白色区域的直方图
phone_hist_mask = cv2.calcHist(images=[phone],channels=[0],mask=mask,histSize=[256],ranges=[0,256])
plt.plot(phone_hist_mask)
plt.show()

mask 掩码:只对图像指定区域做计算,掩码黑色 (0) 区域忽略,白色 (255) 区域参与运算。

掩码:

通过在全黑背景图像中手动将指定矩形区域设置为白色,可以创建一个简易的掩码。此外,也可以基于我们想要分析的目标物体的外接矩形来创建掩码。

得到掩码之后,我们通过 bitwise_and() 对灰度图与掩码图进行位与运算,当两个图像对应位置像素值均为真(非零)时,结果才为真。

效果图:

四、直方图均衡化 cv2.equalizeHist

观察这张女孩图像的直方图可以看出,像素分布并不均衡,灰度值在50之后几乎没有像素分布。现在我们对图像进行直方图均衡化操作,使像素分布变得更加均衡。

python 复制代码
import cv2
import matplotlib.pyplot as plt
import numpy as np

#读取灰度图
black = cv2.imread('black.jpg',cv2.IMREAD_GRAYSCALE)

#均衡化处理
black_equalize = cv2.equalizeHist(black)

#绘制均衡化前直方图
plt.hist(black.ravel(),bins=256)
plt.show()

#绘制均衡化后直方图
plt.hist(black_equalize.ravel(),bins=256)
plt.show()

#横向拼接原图与均衡化结果,对比效果
res = np.hstack((black,black_equalize))
cv2.imshow('black_equalize',res)
cv2.waitKey(0)

经过 cv2.equalizeHist 对像素进行重新分布后,观察直方图可以发现像素分布变得更加均衡。通过对比均衡化前后的女孩图像,可以看出均衡化后的图像特征更加鲜明清晰,对比度显著提高。

五、本章小结

  1. cv2.calcHist()用于统计图像灰度分布;mask掩码可以限定只统计图像局部区域。
  2. np.ravel()将多维图像数组拉伸一维,直接给plt.hist绘图使用。
  3. 掩码配合cv2.bitwise_and()可以提取图像的感兴趣 ROI 区域。
  4. 直方图均衡化 cv2.equalizeHist():输入必须是灰度图,重新分配灰度分布,提升图像对比度,完成图像增强。
  5. 适用场景:图像整体偏暗、偏亮,使用均衡化改善图像显示效果。
相关推荐
AndrewHZ3 小时前
图像处理入门012 | 图像裁剪与缩放:resize 与 ROI 操作
图像处理·opencv·pillow·插值·resize·letterbox·roi
智购科技自动售货机厂家6 小时前
2026自动售货机AI视觉识别优化:从YOLOv11n模型量化到RKNN部署的端侧推理工程实践~YH
javascript·人工智能·yolo·机器学习·计算机视觉·目标跟踪·perl
clorinda6 小时前
OpenCV图像增强基础——图像金字塔、直方图与特征提取
人工智能·opencv·计算机视觉
普密斯科技8 小时前
在线图像测量仪HM-1120如何实现电机轴承从抽检到全检的跨越
计算机视觉·3d·集成测试·测量
zx_741484819 小时前
【计算机视觉入门】基于 OpenCV 的银行卡号识别综合案例
人工智能·opencv·计算机视觉
YOLO数据集集合10 小时前
UAVDT 无人机车辆检测数据集 - 无人机航拍 | 车辆检测 | 目标检测 | YOLO格式 | 智能交通 | 城市管理 | 多类别数据集 | 计算机视觉
人工智能·yolo·目标检测·机器学习·计算机视觉·目标跟踪·无人机
派大_星10 小时前
OpenCV发票图像处理:轮廓检测、透视变换与图像预处理
人工智能·opencv·计算机视觉
闻道且行之1 天前
图片处理助手|泊松融合原理 + C++ 工程实现,seamlessClone 三模式一次讲透
数据库·c++·人工智能·opencv
zmzb01031 天前
Python课后习题训练记录Day194
python·opencv·计算机视觉