计算机视觉(opencv)实战十七——图像直方图均衡化


直方图与直方图均衡化原理详解

图像处理领域中,直方图是一种非常重要的工具,它能够反映一幅图像中像素灰度分布的整体情况。而直方图均衡化则是一种常用的图像增强技术,可以有效改善图像的对比度,使暗部更亮、亮部更亮,从而让细节更加清晰。

本文将通过理论讲解和代码示例,帮助理解直方图及均衡化的原理与应用。


一、直方图的概念与作用

直方图是一种统计图,它记录了图像中各个灰度值出现的次数。

假设图像是 8 位灰度图像,那么每个像素灰度范围是 0~255,直方图就有 256 个柱子,每个柱子代表对应灰度值的像素数量。

  • 横轴:灰度值 (0 ~ 255)。

  • 纵轴:该灰度值的像素出现频率或次数。

直方图能够快速反映图像的亮暗分布:

  • 如果直方图集中在左边,说明图像偏暗;

  • 集中在右边,说明图像偏亮;

  • 集中在中间且分布较窄,说明图像对比度较低,灰度层次不明显;

  • 分布较均匀且覆盖整个灰度范围,说明图像对比度较高,细节丰富。


二、直方图均衡化的原理

1. 问题动机

如果图像的灰度分布比较集中,比如大量像素集中在 100 ~ 150 之间,那么整幅图像会显得灰蒙蒙、对比度低。这种情况就需要对像素的分布进行"拉伸",让灰度值尽可能覆盖整个 0~255 区间。

2. 基本原理

直方图均衡化的核心思想是 重新分配像素灰度值 ,让直方图分布更加均匀。

具体步骤如下:

  1. 统计图像直方图,得到每个灰度值的概率分布;

  2. 计算累积分布函数 (CDF);

  3. 用 CDF 作为映射函数,把原始灰度值映射到新的灰度值,使得像素分布更均匀;

  4. 输出的图像对比度被增强,暗区更亮、亮区更暗,使细节更突出。

这种方法的优点是简单、高效,缺点是可能导致某些图像过度增强,细节丢失或噪声被放大。


三、局部直方图均衡化(CLAHE)

全局直方图均衡化对整幅图像使用同一个映射函数,有时会导致过度增强或亮度不均。为了保留细节,可以使用 自适应直方图均衡化(CLAHE, Contrast Limited Adaptive Histogram Equalization)

CLAHE 将图像分为小块(tiles),在每个小块上分别做直方图均衡化,再把结果拼接起来,从而在局部区域增强对比度。

此外,CLAHE 有一个 clipLimit 参数,用来限制对比度增强的幅度,防止过度增强产生噪声。


四、代码讲解

下面的代码演示了直方图的绘制、全局直方图均衡化以及局部均衡化的效果。

复制代码
# 直方图均衡化:直方图均衡化是一种图像增强技术,它可以通过增加图像的对比度和亮度来改善图像的质量。
# 直方图均衡化通过将图像的像素值分布均匀化来实现这一目标。
# 在Python OpenCV中,可以使用cv2.equalizeHist()函数来实现直方图均衡化。
# 该函数将输入图像转换为灰度图像,并将其像素值分布均匀化,从而增强图像的对比度和亮度。
import cv2
import matplotlib.pyplot as plt
import numpy as np

woman = cv2.imread('face.jpg', cv2.IMREAD_GRAYSCALE)
# # # phone_hist = cv2.calcHist([phone], [0], None, [256], [0,256])
plt.hist(woman.ravel(), bins=256)#numpy中的ravel将数组多维度拉成一维数组
plt.show()

woman_equalize = cv2.equalizeHist(woman)
plt.hist(woman_equalize.ravel(), bins=256)#numpy中的ravel将数组多维度拉成一维数组
plt.show()

res = np.hstack((woman, woman_equalize))#横向拼接,将多个数组按水平方向(列顺序)堆叠成一个新的数组。
cv2.imshow('woman_equalize', res)
cv2.waitKey(0)
# # # 自适应直方图均衡化(局部直方图处理),通过局部调整图像的直方图分布来提升图像的对比度和细节表现力,当需要保存细节特征,需要做局部处理
# # # cv2.createCLAHE([, clipLimit[, tileGridSize]]) → retval
# # # 参数说明:
# # # clipLimit:颜色对比度的阈值,可选项,默认值 8
# # # tileGridSize:局部直方图均衡化的模板(邻域)大小,可选项,默认值 (8,8)
clahe = cv2.createCLAHE(clipLimit=1, tileGridSize=(16, 16))#通过类创建了一个局部均衡化对象
woman_clahe = clahe.apply(woman)
res = np.hstack((woman, woman_equalize, woman_clahe))
cv2.imshow('phone_equalize', res)
cv2.waitKey(0)

代码解析

  1. 加载图像

    使用 cv2.imread(..., cv2.IMREAD_GRAYSCALE) 将图像读为灰度图,便于后续处理。

  2. 绘制原始直方图
    plt.hist(woman.ravel(), bins=256) 统计原始图像灰度分布。ravel() 将二维数组展平,便于统计。

  3. 全局均衡化
    cv2.equalizeHist(woman) 对整幅图像进行直方图均衡化,使直方图分布更均匀。

  4. 显示对比效果
    np.hstack((woman, woman_equalize)) 将原图和均衡化图横向拼接,方便观察效果。

  5. 局部均衡化(CLAHE)

    • clipLimit=1 限制对比度增强,防止噪声放大。

    • tileGridSize=(16, 16) 将图像分为 16x16 小块,每块单独均衡化。

    • clahe.apply(woman) 对原图应用局部均衡化。

  6. 最终显示三图对比

    左图:原始灰度图

    中图:全局均衡化图

    右图:局部均衡化图(对比度提升更明显,细节保留更好)


五、应用场景

  • 医学影像:增强 X 光片、CT 图像的细节,使病灶更清晰;

  • 工业检测:增强低对比度图像,提高缺陷检测的准确率;

  • 夜间监控:提高暗光环境下图像可见性;

  • OCR 识别:提升文档对比度,减少噪声干扰,提高文字识别准确率。


六、总结

直方图是分析图像亮度分布的重要工具,而直方图均衡化能够有效提升图像对比度。

全局均衡化简单高效,但可能会损失局部细节;自适应直方图均衡化(CLAHE)通过分块处理,可以更好地保留局部细节,增强效果更自然。

通过本文及代码演示,可以直观理解直方图均衡化的原理与实际效果,掌握其在图像增强中的应用。


要不要我帮你画一张示意图,展示直方图均衡化前后灰度分布的变化(比如用两张直方图对比)?这样文章会更直观。

相关推荐
迁移科技1 分钟前
案例丨AI+3D视觉,赋能制药行业拆垛及破包更精准高效
人工智能·科技·3d·自动化·视觉检测
NQBJT6 分钟前
万字拆解 NeckFix:AI 脖子前倾检测的算法原理与工程实现
人工智能·算法
数智工坊12 分钟前
【Inner Monologue论文阅读】: 首次将大语言模型嵌入机器人控制闭环,实现自我反思和动态行为调整
论文阅读·人工智能·算法·语言模型·机器人·无人机
AI帮小忙19 分钟前
Debian/Ubuntu 系linux操作系统Kali Linux 2026 里安装 Hermes Agent
人工智能
乌恩大侠21 分钟前
基站正在成为 AI 计算节点:NVIDIA Aerial 推动 RAN 架构重构
人工智能·重构·架构
钓了猫的鱼儿26 分钟前
基于深度学习+AI的水下目标目标检测与预警系统(Python源码+数据集+UI可视化
人工智能·深度学习·智能手机
Ting-yu30 分钟前
Spring AI Alibaba零基础速成(6) ---- 向量化
数据库·人工智能
YUDAMENGNIUBI32 分钟前
day29_NLP概念与文本预处理
人工智能·自然语言处理
南屹川32 分钟前
【安全】代码安全审计与防护实践
人工智能
深开鸿35 分钟前
福田区全栈式鸿蒙AI数智机关入选全市首批OR示范应用项目,深开鸿筑牢政务安全底座
人工智能·openharmony·政务