Python数字图像处理:直方图均衡化

直方图均衡化(Histogram Equalization)是一种通过调整图像灰度分布来增强图像对比度的经典方法,尤其在处理低对比度或光照不均匀的图像时效果显著。本文深入解析其数学原理,并提供手动实现 与OpenCV优化方案的完整代码,结合实际应用场景展示其核心价值。

1. 直方图均衡化原理

(1) 核心目标
  • 问题:图像灰度集中在狭窄范围 → 细节模糊。
  • 解决方案 :将原始直方图变换为均匀分布,扩展动态范围。
(2) 数学推导
  1. 概率密度函数(PDF) :
    统计各灰度级频数:
  1. 累积分布函数(CDF):

将映射到新的灰度级,使新直方图接近均匀分布。

2. 手动实现直方图均衡化

(2.1) 灰度图像处理
复制代码
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

def manual_hist_equalize(image):
    if len(image.shape) == 3:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    hist = cv2.calcHist([image], [0], None, [256], [0, 256])
    hist_norm = hist.ravel() / hist.sum()  # 归一化得到PDF
    cdf = hist_norm.cumsum()               # 计算CDF
    cdf_normalized = (cdf * 255).astype(np.uint8)  # 线性映射到0-255
    return cdf_normalized[image]  # 应用映射

# 使用示例
img = cv2.imread('5.bmp', cv2.IMREAD_GRAYSCALE)

if img is None:
    print("错误:无法加载图像,请检查文件路径。")
else:
    equalized_manual = manual_hist_equalize(img)

    # 显示原始图像和直方图均衡化后的图像
    plt.figure(figsize=(10, 5))

    plt.subplot(1, 2, 1)
    plt.title('原始图像')  # 中文标题
    plt.imshow(img, cmap='gray')

    plt.subplot(1, 2, 2)
    plt.title('手动直方图均衡化图像')  # 中文标题
    plt.imshow(equalized_manual, cmap='gray')

    plt.show()
(2.2) 关键步骤解析
步骤 功能 代码实现
统计直方图 计算各灰度级像素数量 cv2.calcHist
归一化PDF 转换为概率分布 hist_norm = hist / total
计算CDF 累加概率密度,生成映射函数 cdf = np.cumsum(hist_norm)
应用映射 将原图灰度替换为CDF对应值 equalized = cdf[original]

3. OpenCV高效实现

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

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 灰度图直方图均衡化
def gray_hist_equalize(image):
    if len(image.shape) == 3:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    equalized = cv2.equalizeHist(image)
    return equalized

# 彩色图直方图均衡化
def color_hist_equalize(image):
    # 将图像转换为 YCrCb 色彩空间
    ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb)
    # 对 Y 通道进行直方图均衡化
    ycrcb[:, :, 0] = cv2.equalizeHist(ycrcb[:, :, 0])
    # 转换回 BGR 色彩空间
    equalized = cv2.cvtColor(ycrcb, cv2.COLOR_YCrCb2BGR)
    return equalized

# 加载图像
img = cv2.imread('5.bmp')

if img is None:
    print("错误:无法加载图像,请检查文件路径。")
else:
    # 灰度图处理
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray_equalized = gray_hist_equalize(img)

    # 彩色图处理
    color_equalized = color_hist_equalize(img)

    # 将 BGR 图像转换为 RGB 图像(matplotlib 使用 RGB 格式)
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    color_equalized_rgb = cv2.cvtColor(color_equalized, cv2.COLOR_BGR2RGB)

    # 使用 matplotlib 显示图像
    plt.figure(figsize=(15, 10))

    # 显示原始图像
    plt.subplot(2, 2, 1)
    plt.imshow(img_rgb)
    plt.title('原始彩色图像')
    plt.axis('off')

    # 显示原始灰度图像
    plt.subplot(2, 2, 2)
    plt.imshow(gray_img, cmap='gray')
    plt.title('原始灰度图像')
    plt.axis('off')

    # 显示灰度直方图均衡化图像
    plt.subplot(2, 2, 4)
    plt.imshow(gray_equalized, cmap='gray')
    plt.title('灰度直方图均衡化图像')
    plt.axis('off')

    # 显示彩色直方图均衡化图像
    plt.subplot(2, 2, 3)
    plt.imshow(color_equalized_rgb)
    plt.title('彩色直方图均衡化图像')
    plt.axis('off')

    # 显示图像
    plt.tight_layout()
    plt.show()
相关推荐
浅念-2 小时前
动态规划:线性DP——多状态DP与子数组专题笔记
c++·笔记·算法·leetcode·职场和发展·动态规划·力扣
雪雪爱冲浪2 小时前
JavaScript 网络爬虫教程(2026)
开发语言·javascript·爬虫
Data analyse4562 小时前
rrweb回放事件资源加载顺序重放校验
前端·人工智能·算法·机器学习·数据分析
昨夜见军贴06162 小时前
原始采样记录数字化落地,IACheck AI 报告文档审核 Agent 实现监测文档校验自动化
人工智能·算法·自动化
ueotek2 小时前
Ansys Zemax丨在 OpticStudio 中拟合折射率数据
python·软件工程·ansys·光学仿真·光学设计·zeamx
要吃这碗饭2 小时前
JavaScript 网络爬虫教程(2026)
开发语言·javascript·爬虫
czq_26867194872 小时前
Python打卡第40天
开发语言·python
yangmu32032 小时前
Unity 开发过程与底层原理
java·开发语言
不爱吃鱼的蔓热莓2 小时前
Autosar之根据ARXML中报文信息生成SWC(二)
开发语言·python
奈葵2 小时前
Python语句
开发语言·python