OpenCV 直方图均衡化的实现原理解析
前言
图像处理涉及到众多的算法和方法,而图像增强是其中一大类。在这类算法中,直方图均衡化(Histogram Equalization)被广泛应用。该算法背后的原理是调整图像的灰度级使其均匀分布,从而增强图像的对比度。
直方图均衡化的实现原理
在 OpenCV 中,直方图均衡化是通过 cv2.equalizeHist()
函数实现的。该函数接受单通道图像作为输入,并返回均衡化后的图像。
直方图均衡化的实现过程如下:
- 计算输入图像的像素直方图
- 计算归一化累计直方图
- 计算输出像素值
- 将输出像素值映射回图像中
计算输入图像的像素直方图
像素直方图是图像中各个像素值的出现次数统计图。它可以指导我们了解图像亮度的分布状况。在计算过程中,我们需要遍历图像中的每个像素并计算它的像素值。最后,我们将它们计算到直方图中。
以下是一个计算像素直方图的 OpenCV 示例代码:
import cv2
import numpy as np
img = cv2.imread('image.png', 0)
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
在这段代码中,使用 cv2.imread()
函数读入一张灰度图像,并使用 cv2.calcHist()
函数计算直方图。我们可以将 hist
打印到屏幕上了解到图像的灰度级分布情况。
计算归一化累计直方图
归一化累计直方图是在像素直方图的基础上得出来的。它除了考虑像素值外,还将其乘以间隔宽度,这一步被称为归一化。这种方式不同的灰度值之间的权重,可以在均衡化过程中发挥作用。计算后即可获得归一化的累计直方图。
OpenCV 中 cv2.equalizeHist()
函数所用的累计直方图是归一化的。以下是一个计算归一化累计直方图的 OpenCV 示例代码:
import cv2
import numpy as np
img = cv2.imread('image.png', 0)
hist, bins = np.histogram(img.flatten(), 256, [0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'b')
plt.hist(img.flatten(), 256, [0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()
计算输出像素值
当前的像素值不能作为最终的输出值,需要计算一个新的像素值来实现均衡化。新的像素值是归一化累积直方图的插值结果。,通过统计累计直方图,我们可以得到灰度级映射表。新的像素值即为以当前像素值为下标的累积分布函数值。在 OpenCV 中,相应的代码如下:
import cv2
import numpy as np
img = cv2.imread('image.png', 0)
hist, bins = np.histogram(img.flatten(), 256, [0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint8')
img2 = cdf[img]
在这段代码中,我们通过计算 cdf
来获取灰度级映射表,并将其应用到原始图像 img
中,从而获得均衡化后的图像 img2
。
将输出像素值映射回图像中
通过上面的步骤,我们已经得到了均衡化后的图像 img2
。现在,将其重新映射回原始的灰度级,我们就可以获取到最终的均衡化图像了。在 OpenCV 中,相应的代码如下:
import cv2
import numpy as np
img = cv2.imread('image.png', 0)
hist, bins = np.histogram(img.flatten(), 256, [0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint8')
img2 = cdf[img]
cv2.imshow('Original Image', img)
cv2.imshow('Equalized Image', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
总结
直方图均衡化是一种常见的图像增强方法,是所有图像处理人员必须掌握的技能之一。通过本文的讲解,您已经掌握了 OpenCV 中直方图均衡化的实现原理和应用方法。希望您能够在今后的工作中熟练地应用这一技能,并取得更好的图像增强效果。
参考
- Python OpenCV Tutorial - Find Lanes for Self-Driving Cars (Computer Vision Basics Tutorial)
- OpenCV Tutorial: Histogram Equalization
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:OpenCV 直方图均衡化的实现原理解析 - Python技术站