直方图均衡化:一步一步的指南(CV-06)

23d6496d17db19eadb9f1bac62c7e0eb.png

动机

直方图是用条形图进行频率分布可视化的过程。在计算机视觉中,图像直方图是用条形图表示强度值频率的过程。通过图像直方图均衡化,我们可以轻松调整图像强度频率的分布。通常,这个过程帮助我们增加图像的对比度和亮度。这个过程简单易行。本文将讨论直方图均衡化的完整过程,并附有编程示例。

目录
  1. 图像直方图

  2. 直方图均衡化的完整过程

  3. 逐步实施

图像直方图

图像直方图是用条形图表示图像强度值频率的表示。在图-1中,我展示了一张带有其强度值的样本图像在二维空间中的表示。

8773d7413c49dee2b36f16ee8de565d7.png

数值范围从0到7。让我们计算这些值的频率。

f9b8edc2e2d73bbf079362ce7efb3ac9.png

图像直方图是频率对强度值的简单表示,用条形图表示,如图-3所示。

85e02d34a9fb4f35b0f25427c400c41c.png
直方图均衡化的完整过程

直方图均衡化是通过一些函数均匀分布图像强度值的频率的过程。主要的函数是概率函数(Probability Density Function,PDF)和累积分布函数(Cumulative Distribution Function,CDF)。

  • PDF是通过强度值的频率除以总频率计算的。

  • CDF保存小于或等于特定值的概率分布的概率。例如,强度值0的PDF → 0.12,1的PDF → 0.24,2的PDF → 0.12,等等。因此,1的CDF为0.12+0.24=0.36,2的CDF为0.36+0.12=0.48,以此类推。整个结果编制在图-4中。

eeacdf00e913e0394fe370fa22419b8d.png

最后,我们需要用整数乘以CDF。

选择数值的过程—

图像的最大强度值是7,如图-1所示。我们必须选择一个满足以下公式的整数。

02b3c6dbb403983c3bd95dc28fe37c34.png

在这里,x是表示最大强度值的比特数的最小值。对于我们的情况,最大值是7,(2³-1 = 7)。如果我们选择x的值为2,就不能表示最大强度值。因此,在我们的情况下,最优的乘法值是7。

最后,我们将乘法结果四舍五入,得到均衡直方图值。将强度值替换为均衡直方图值以获得最终输出。整个过程如图-5所示。

db0c6d0d2bdf3a48cc55bfa35677149e.png

为了应用直方图均衡化,我们需要用均衡的直方图值替换初始强度值。

新图像将如下所示—

31c846e700905ab5b6cd7451d70ee613.png

均衡直方图强度值的频率与先前的频率不同,如图-6所示。

355c9c4604040d75560d9baba9db2e64.png

图-7展示了图像强度频率的比较。

aad91968d6c3a1ad04516e84ac8c2c8e.png

如果我们观察均衡直方图频率与初始频率的比较,我们会发现均衡直方图的强度值比初始值高,如图-7所示。

现在是时候用Python进行实际操作了……

逐步实施

为了实施直方图均衡化,我们使用OpenCV库。

  • 让我们导入必要的库并读取灰度图像—

import cv2
import numpy as np
import matplotlib.pyplot as plt
beach=cv2.imread('mountain.jpg',cv2.IMREAD_GRAYSCALE)
plt.imshow(beach, cmap='gray')
<matplotlib.image.AxesImage at 0x7faba740ee20>
b1c04bd8223fd1d3ab0b4e8930f307b8.png
  • 计算图像的频率并绘制直方图—

hist_values = cv2.calcHist([beach],channels=[0],mask=None,histSize=[256],ranges=[0,256])
plt.plot(hist_values)
plt.xlabel('Intensity Value')
plt.ylabel('Frequency')
plt.show()
ef3338d1f00a22a22390dd2c90120493.png

由于大多数图像部分较暗,低强度值(~0)的频率大于高强度值。

  • OpenCV函数cv2.equalizeHist()有助于实现直方图均衡化—

eql = cv2.equalizeHist(beach)
plt.imshow(eql,cmap='gray')
<matplotlib.image.AxesImage at 0x7faba72b3610>
64b74a642f464e0f0eebca618d4e753e.png

如果我们仔细观察输出图像,我们可能会注意到图像的亮度比原始图像更高。

  • 让我们设置均衡的直方图图—

eql_hist = cv2.calcHist([eql],channels=[0],mask=None,histSize=[256],ranges=[0,256])
plt.plot(eql_hist)
plt.xlabel('Intensity Value')
plt.ylabel('Frequency')
plt.show()
495a2f1b1e8b5f24d114af1d6b8479b0.png

强度值的频率比原始图像更均匀分布。

处理彩色图像

RGB/BGR图像有3个通道—红色、绿色和蓝色。为了在图像上应用直方图均衡化,我们需要将RGB/BGR图像转换为HSV(色调、饱和度和值)图像。最后,我们将直方图均衡化应用于HSV图像的值参数,并将其转换为RGB图像进行可视化。

clr_mountain=cv2.imread('mountain.jpg')
# OpenCV reads the image in a BGR format. so we convert it to RGB for visualizatoin 
clr_RGB=cv2.cvtColor(clr_mountain,cv2.COLOR_BGR2RGB) 
#we need to convert the image to HSV format for applying histogram equalization
clr_hsv=cv2.cvtColor(clr_mountain,cv2.COLOR_BGR2HSV)

plt.imshow(clr_RGB)
<matplotlib.image.AxesImage at 0x7faba73d7640>
c16b835ae9087445ffbb4de8c350ffb5.png
  • 应用直方图均衡化并将其转换为RGB图像,以便使用matplotlib进行可视化。

clr_hsv[:,:,2]=cv2.equalizeHist(clr_hsv[:,:,2])
clr=cv2.cvtColor(clr_hsv,cv2.COLOR_HSV2RGB)
plt.imshow(clr)
<matplotlib.image.AxesImage at 0x7fab9e9be250>
99a9a6d7461f8cf721c5eb27b45ab854.png

很明显,图像的亮度和对比度显著增加。

如果你愿意,你可以绘制先前显示的直方图和均衡的直方图。

结论

我们生活在一个生成式人工智能的世界。这些基本的计算机视觉技术看起来非常基础和过时,但它们是构建强大模型或创新的基础。因此,我始终强调知识的基础。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

3b7bf57a1619a5de441283c3bb2b0cb9.jpeg

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值