OpenCV基础(16)OpenCV直方图均衡化和自适应直方图均衡化(CLAHE)

在本教程中,您将学习使用OpenCV实现直方图均衡化和自适应直方图均衡化(CLAHE)。

直方图均衡化是一种基本的图像处理技术,通过更新图像直方图的像素强度分布来调整图像的全局对比度。这样做可以使低对比度的区域在输出图像中获得更高的对比度。

本质上,直方图均衡化的工作原理是:

  • 1.计算图像像素强度的直方图
  • 2.均匀展开并分布最频繁的像素值(即直方图中计数最大的像素值)
  • 3.给出累积分布函数(CDF)的线性趋势

应用直方图均衡化的结果是得到一幅全局对比度更高的图像。

我们可以进一步改进直方图均衡化,采用一种称为对比度有限自适应直方图均衡化(CLAHE)的算法,从而获得更高质量的输出图像。

除了摄影师使用直方图均衡化来校正曝光不足/过曝光的图像外,直方图均衡化使用最广泛的是在医疗领域。

你通常会看到直方图均衡化应用于x光扫描和CT扫描,以提高x光片的对比度。这样做可以帮助医生和放射科医生更好地解释扫描结果,做出准确的诊断。

在本教程结束时,您将能够成功地使用OpenCV将基本直方图均衡化和自适应直方图均衡化应用到图像。

1.OpenCV直方图均衡化和自适应直方图均衡化(CLAHE)

在本教程的第一部分,我们将讨论什么是直方图均衡化,以及如何使用OpenCV应用直方图均衡化。
代码地址:

链接:https://pan.baidu.com/s/19V6s7Ten6K9FfBpJTbZhAQ 
提取码:123a

我们将实现两个Python脚本:

  • simple_equalization.py:使用OpenCV的cv2.equalizeHist()函数执行基本直方图均衡。
  • adaptive_equalization.py:使用OpenCV的cv2.createCLAHE()方法执行自适应直方图均衡化。

2.什么是直方图均衡化?

直方图均衡化是一种基本的图像处理技术,可以提高图像的整体对比度。

应用直方图均衡化首先计算输入灰度/单通道图像中像素强度的直方图:
在这里插入图片描述
左 : 我 们 的 原 始 输 入 灰 度 图 像 。 右 : 计 算 灰 度 图 像 的 直 方 图 。 左:我们的原始输入灰度图像。右:计算灰度图像的直方图。
请注意,我们的直方图有许多峰值,这表明有很多像素被归入到这些各自的bin中。使用直方图均衡化,我们的目标是将这些像素分散到没有太多像素的bin中。

从数学上来说,这意味着我们试图将线性趋势应用到累积分布函数(CDF)中:
在这里插入图片描述
直 方 图 均 衡 化 目 标 使 输 出 图 像 具 有 线 性 C D F 直方图均衡化目标使输出图像具有线性CDF 使线CDF
在这里插入图片描述
左 : 应 用 直 方 图 均 衡 化 之 前 的 原 始 输 入 图 像 。 右 : 应 用 直 方 图 均 衡 化 后 的 输 出 图 像 。 左:应用直方图均衡化之前的原始输入图像。右:应用直方图均衡化后的输出图像。
注意输入图像的对比度是如何显著提高的,但代价是也提高了输入图像中的噪声的对比度。

这就提出了一个问题:是否有可能在不增加噪声的同时提高图像对比度?
答案是“是的”,你只需要应用自适应直方图均衡化。

通过自适应直方图均衡化,我们将输入图像划分为M × N网格。然后我们对网格中的每个单元进行均衡处理,从而获得更高质量的输出图像:

在这里插入图片描述
左 : 基 本 直 方 图 均 衡 。 右 : 自 适 应 直 方 图 均 衡 化 左:基本直方图均衡。右:自适应直方图均衡化
缺点是,自适应直方图均衡化的计算复杂度更高(但考虑到现代硬件,这两种实现仍然相当快)。

3.如何使用OpenCV进行直方图均衡化?

OpenCV 包括通过以下两个函数实现基本直方图均衡和自适应直方图均衡:

  • cv2.equalizeHist
  • cv2.createCLAHE

应用cv2.equalizeHist()函数非常简单,只需将图像转换为灰度,然后调用cv2.equalizeHist即可:

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
equalized = cv2.equalizeHist(gray)

实现自适应直方图均衡化要求:

  • 1.将输入图像转换为灰度/从中提取单个通道
  • 2.使用cv2.createCLAHE实例化CLAHE算法
  • 3.在CLAHE对象上调用.apply()方法来应用直方图均衡化

这比听起来容易得多,只需要几行代码:

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
equalized = clahe.apply(gray)

注意,我们为cv2.createCLAHE提供了两个参数:

  • clipLimit:这是对比度限制的阈值
  • tileGridSize:将输入图像划分为M × N块,然后对每个局部块应用直方图均衡化

4.项目结构

在我们使用OpenCV实现直方图均衡化之前,让我们先回顾一下我们的项目目录结构。
在这里插入图片描述

5.代码实现

5.1 使用OpenCV实现标准直方图均衡化

#   用法
# python simple_equalization.py --image images/moon.png

# 导入必要的库
import argparse
import cv2

# 构造参数解析器并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str, required=True, help="Path to the input image")
args = vars(ap.parse_args())

# 从磁盘加载输入图像并将其转换为灰度
print("[INFO] Loading input image...")
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 运用直方图均衡化
print("[INFO] Performing histogram equalization...")
equalized = cv2.equalizeHist(gray)

# 显示原始灰度图像和均衡后的图像
cv2.imshow("Input", gray)
cv2.imshow("Histogram Equalization", equalized)
cv2.waitKey(0)

在这里插入图片描述

5.2代码解析

首先导入我们需要的 Python 包,解析我们的命令行参数。这里我们只需要一个参数–image,它是磁盘上输入图像的路径,我们希望在这里应用直方图均衡化。

解析完命令行参数后,我们可以继续下一步:从磁盘加载图像,将图像从RGB转换为灰度。使用cv2.equalizeHist执行基本的直方图均衡化。我们必须传入的唯一必需参数是灰度/单通道图像。

注:使用OpenCV进行直方图均衡化时,必须提供灰度/单通道图像。如果我们试图传递一个多通道图像,OpenCV将抛出一个错误。要在多通道图像上执行直方图均衡化,您需要(1)将图像分割成各自的通道,(2)均衡每个通道,(3)合并通道。

5.3 使用OpenCV实现自适应直方图均衡

#   用法
# python adaptive_equalization.py --image images/boston.png
# 导入必要的库
import argparse
import cv2

# 构造参数解析器并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str, required=True, help="Path to the input image")
ap.add_argument("-c", "--clip", type=float, default=2.0, help="Threshold for contrast limiting")
ap.add_argument("-t", "--tile", type=int, default=8,
                help="Tile grid size -- divides image into tile x tile cells")
args = vars(ap.parse_args())

# 从磁盘加载输入图像并将其转换为灰度
print("[INFO] Loading input image...")
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 应用CLAHE (Contrast Limited Adaptive Histogram Equalization)
print("[INFO] Applying CLAHE...")
clahe = cv2.createCLAHE(clipLimit=args["clip"], tileGridSize=(args["tile"], args["tile"]))
equalized = clahe.apply(gray)

# 显示原始灰度图像和CLAHE输出图像
cv2.imshow("Input", gray)
cv2.imshow("CLAHE", equalized)
cv2.waitKey(0)

在这里插入图片描述
在这里插入图片描述

5.4代码解析

自适应直方图均衡化比简单直方图均衡化的计算代价高一些,但可以产生更好的结果。但是不要相信我的话——你应该自己看看结果。

我们有三个命令行参数,其中一个是必需的,二个是可选的(但在使用CLHE时很有用):

  • --image:磁盘上输入图像的路径,我们希望在其中应用直方图均衡化。
  • --clip:对比度限制的阈值。您通常希望将此值保留在 2-5 的范围内。如果您将该值设置得太大,那么实际上您所做的是最大化局部对比度,这反过来又会最大化噪声(这与您想要的相反),尽量保持该值尽可能低。
  • --tile:CLAHE 的网格大小。从概念上讲,我们在这里所做的是将输入图像划分为 tile x tile 单元格,然后对每个单元格应用直方图均衡(使用 CLAHE 提供的额外功能)。

从磁盘加载输入图像并将其转换为灰度,就像我们对基本直方图均衡化所做的那样。通过cv2.createCLAHE()函数初始化CLHE对象。这里,我们提供了clipLimittileGridSize,它们是通过命令行参数提供的。

调用.apply()方法将自适应直方图均衡化应用于灰度图像。

6.直方图均衡化的建议

在构建自己的图像处理管道并发现应该应用直方图均衡化时,我建议从使用 cv2.equalizeHist 的简单直方图均衡化开始。但是如果你发现结果很差,反而增加了输入图像的噪声,那么你应该尝试通过 cv2.createCLAHE 使用自适应直方图均衡化。

参考目录

https://www.pyimagesearch.com/2021/02/01/opencv-histogram-equalization-and-adaptive-histogram-equalization-clahe/

  • 12
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值