计算机视觉基础 第 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. 适用场景:图像整体偏暗、偏亮,使用均衡化改善图像显示效果。
相关推荐
2601_962300478 小时前
halconpython联合开发网_C#与Halcon联合开发实例,并做了可移动的ROI库
图像处理·c·halcon·软件开发·roi
Evand J10 小时前
【MATLAB例程,图像降噪滤波9】自适应维纳滑动窗口滤波(Wiener)图像降噪、方法对比,有中文注释
开发语言·图像处理·计算机视觉·matlab·滑动窗口·滤波·降噪
小蒋观天下10 小时前
社区AI智能摄像头完整选型指南
大数据·人工智能·安全·计算机视觉·语音识别·ai大模型
泡干脆面就番茄15 小时前
03_LBPH人脸识别算法原理与实战
python·opencv
YOLO数据集集合15 小时前
天空反无人机检测数据集 | 无人机检测 多旋翼识别 固定翼识别 低空安防 目标检测9063期
人工智能·yolo·目标检测·计算机视觉·无人机·反无人机
深度学习lover17 小时前
<数据集>蚜虫识别<目标检测>
人工智能·深度学习·yolo·目标检测·计算机视觉·蚜虫识别
A hao18 小时前
LED视频处理器中帧率与刷新率的区别
大数据·图像处理·人工智能·音视频
程序猿编码18 小时前
纯C++轻量计算机视觉推理引擎:基于GGML的端侧CV模型部署技术全解析
开发语言·c++·计算机视觉·大模型·transformer
m0_6145235519 小时前
批量商品图换背景如何返工:建立逐图状态和问题清单
图像处理
深圳雨林凯AI19 小时前
印花提取的批量工程:底色分离、品牌字剔除与线条锐利度的技术拆解
图像处理·人工智能