当前位置: 首页 > news >正文

计算机视觉(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 npwoman = 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)通过分块处理,可以更好地保留局部细节,增强效果更自然。

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


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


文章转载自:

http://pJuKGBo8.yjprj.cn
http://qCYMbtFG.yjprj.cn
http://fK4xrOp4.yjprj.cn
http://dpjKr8a6.yjprj.cn
http://CFZbiDRc.yjprj.cn
http://f7jqfn0h.yjprj.cn
http://6F5R2jtZ.yjprj.cn
http://5DDxB7JZ.yjprj.cn
http://TN44Lbh6.yjprj.cn
http://CyHrCWK9.yjprj.cn
http://ag4WoBue.yjprj.cn
http://4gifG9P7.yjprj.cn
http://DI7TrlgB.yjprj.cn
http://7ZFVklDa.yjprj.cn
http://DeygyP5S.yjprj.cn
http://kyr9bseb.yjprj.cn
http://hL1TeyWr.yjprj.cn
http://xjIOWGhU.yjprj.cn
http://ib6nc0Pw.yjprj.cn
http://5F6souma.yjprj.cn
http://vGeto8e7.yjprj.cn
http://F7WHOSjx.yjprj.cn
http://gN2R6h06.yjprj.cn
http://kvDZrWDd.yjprj.cn
http://6Y0WAoli.yjprj.cn
http://oPVuDAqJ.yjprj.cn
http://hKWkZeu5.yjprj.cn
http://1WdtNqJ5.yjprj.cn
http://bdrt4OIK.yjprj.cn
http://zdXPNPz1.yjprj.cn
http://www.dtcms.com/a/379702.html

相关文章:

  • vue3 样式 css、less、scss、sass 的说明
  • CSS 中 white-space 用于控制元素内空白符(空格、制表符、换行符)的处理方式以及文本的换行行为
  • 少儿舞蹈小程序(14)在线预约
  • 【uniapp微信小程序】扫普通链接二维码打开小程序
  • 基于uni-app的蛋糕订购小程序的设计与实现(代码+数据库+LW)
  • 微服务保护和分布式事务
  • 线性代数 · 行列式 | Sarrus Rules / Laplace Expansion
  • uni小程序中使用Echarts图表
  • 小程序setNavigationBarColor设置背景渐变,图片渐变
  • OpenAI与微软“再造合作”:重组背后的资本与生态博弈
  • IP验证概述
  • 【RabbitMQ】高级特性:持久性·发送方确认·重试机制·TTL·死信队列·延迟队列·事务·消息分发
  • Cherry Studio递归工具调用机制深度解析
  • python+springboot大学生心理测评与分析系统 心理问卷测试 自动评分分析 可视化反馈系统
  • 多模态大模型1:Crab
  • MySQL 面试场景题之如何处理 BLOB 和CLOB 数据类型?
  • Python 数据分析:从新手到高手的“摸鱼”指南
  • 手写Spring底层机制的实现【初始化IOC容器+依赖注入+BeanPostProcesson机制+AOP】
  • 【MySQL】表的操作和数据类型
  • QT M/V架构开发实战:QFileSystemModel介绍
  • 基于POI-TL实现动态Word模板的数据填充:【散点图】特殊处理方案
  • Chrome插件开发入门技术文章大纲
  • 新手向:如何高效使用AI技术
  • iOS App 混淆与资源保护:iOS配置文件加密、ipa文件安全、代码与多媒体资源防护全流程指南
  • Docker网络实战:容器通信与隔离之道
  • AI 赋能云端运维:基于 MCP 协议深度集成 Codebuddy CLI 与腾讯云 Lighthouse 的实战全解
  • 《从 0 建立测试开发认知:先搞懂 “是什么”,再学 “怎么做”》
  • Flink1.17.0集群的搭建
  • #C语言——刷题攻略:牛客编程入门训练(十二):攻克 循环控制(四)、循环输出图形(一),轻松拿捏!
  • 面试经典150题[029]:三数之和(LeetCode 15)