OpenCV equalizeHist()函数:直方图均衡化(附带实例)
在一线开发中,一般直接使用 equalizeHist() 函数对图像进行直方图均衡化(归一化图像亮度和增强图像对比度),其声明如下:
直方图均衡化有 3 种,分别是灰度图像直方图、彩色图像直方图以及 YUV 直方图均衡化。
灰度图像直方图均衡化的示例如下:
下面我们使用 OpenCV 提供的均衡化函数 equalizeHist() 实现彩色图像的直方图均衡化。
彩色图像的直方图均衡化和灰度图像略有不同,需要先用 split() 方法将彩色图像的三个通道拆分,然后分别进行均衡化,最后使用 merge() 方法将均衡化后的三个通道合并。
【实例】实现彩色图像的直方图均衡化。
有没有觉得结果图的色彩有点太鲜艳了?直方图均衡化通常是对单通道图像进行的,如果对多通道图像的每个通道分别进行均衡化,可能会出现一些色彩被增强得过分鲜艳的情况。因此,对于多通道彩色图像,经常先将其转换为 YUV 色彩空间,然后只对 Y 通道进行均衡化,此时的效果将更好。
YUV 是一种色彩编码模型,也叫作 YCrCb,其中“Y”表示明亮度(Luminance),“U”和“V”分别表示色度(Chrominance)和浓度(Chroma)。YUV 色彩编码模型,其设计初衷是为了解决彩色电视机与黑白电视机的兼容问题,它利用了人类眼睛的生理特性(对亮度敏感,对色度不敏感),允许降低色度的带宽,从而降低了传输带宽。
YUV 在计算机系统中的应用尤为广泛,利用 YUV 色彩编码模型可以降低图片数据的内存占用,提高数据处理效率。另外,YUV 编码模型的图像数据一般不能直接用于显示,还需要将其转换为RGB(RGBA)编码模型,才能够正常显示图像。YCrCb 色彩空间用亮度 Y,红色 Cr、蓝色 Cb 表示图像。
从 BGR 色彩空间转换为 YCrCb 色彩空间的计算公式为:
YUV 直方图均衡化的例子如下:
要均衡 Y 通道,需先分解出通道,然后均衡化,最后合并通道。OpenCV 提供了一个 split 方法,直接传入图片就可以分离通道。
均衡化后,要将均衡化后的三个通道合并为一张彩色图片,这时需要使用 merge 方法。merge 方法将三个通道传入其中作为参数,返回的结果就是合并后的彩色图像值。
运行工程,结果如下图所示:
可以看出,均衡化后的图像的亮度和对比度增强了,但颜色没有变得特别鲜艳。因此只对 Y 通道进行均衡化,效果更好。
equalizeHist(src[, dst]) -> dst其中,参数 src 表示输入图像,即原图像,但需要为8位单通道的图像;dst 表示输出结果,需要和原图像有一样的尺寸和类型。
直方图均衡化有 3 种,分别是灰度图像直方图、彩色图像直方图以及 YUV 直方图均衡化。
灰度图像直方图均衡化的示例如下:
import cv2 import numpy as np img = cv2.imread("test.jpg", 1) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imshow("src", gray) dst = cv2.equalizeHist(gray) cv2.imshow("dst", dst) cv2.waitKey(0)将灰度图像作为参数传进 equalizeHist() 方法即可。运行工程,结果如下图所示。

下面我们使用 OpenCV 提供的均衡化函数 equalizeHist() 实现彩色图像的直方图均衡化。
彩色图像的直方图均衡化和灰度图像略有不同,需要先用 split() 方法将彩色图像的三个通道拆分,然后分别进行均衡化,最后使用 merge() 方法将均衡化后的三个通道合并。
【实例】实现彩色图像的直方图均衡化。
import cv2 import numpy as np img = cv2.imread("test.jpg", 1) cv2.imshow("src", img) # 彩色图像均衡化,需要先分解通道再对每一个通道均衡化 (b, g, r) = cv2.split(img) bH = cv2.equalizeHist(b) gH = cv2.equalizeHist(g) rH = cv2.equalizeHist(r) # 合并每一个通道 result = cv2.merge((bH, gH, rH)) cv2.imshow("dst", result) cv2.waitKey(0)运行工程,结果如下图所示。从结果图片上可以看出,相比原图,直方图均衡化后的图片的对比度和亮度都被增强了不少。

有没有觉得结果图的色彩有点太鲜艳了?直方图均衡化通常是对单通道图像进行的,如果对多通道图像的每个通道分别进行均衡化,可能会出现一些色彩被增强得过分鲜艳的情况。因此,对于多通道彩色图像,经常先将其转换为 YUV 色彩空间,然后只对 Y 通道进行均衡化,此时的效果将更好。
YUV 是一种色彩编码模型,也叫作 YCrCb,其中“Y”表示明亮度(Luminance),“U”和“V”分别表示色度(Chrominance)和浓度(Chroma)。YUV 色彩编码模型,其设计初衷是为了解决彩色电视机与黑白电视机的兼容问题,它利用了人类眼睛的生理特性(对亮度敏感,对色度不敏感),允许降低色度的带宽,从而降低了传输带宽。
YUV 在计算机系统中的应用尤为广泛,利用 YUV 色彩编码模型可以降低图片数据的内存占用,提高数据处理效率。另外,YUV 编码模型的图像数据一般不能直接用于显示,还需要将其转换为RGB(RGBA)编码模型,才能够正常显示图像。YCrCb 色彩空间用亮度 Y,红色 Cr、蓝色 Cb 表示图像。
从 BGR 色彩空间转换为 YCrCb 色彩空间的计算公式为:
Y = 0.299R + 0.587G + 0.114B Cr = 0.713(R - Y) + delta Cb = 0.564(B - Y) + delta其中,delta = 128(8位图像)、delta = 32767(16位图像)、delta = 0.5(单精度图像)。在 cv2.cvtColor 函数中使用 cv2.COLOR_BGR2YCrCb转 换码可将图像从 BGR 色彩空间转换为 YCrCb 色彩空间;使用 cv2.COLOR_YCrCb2BGR 转换码可将图像从 YCrCb 色彩空间转换为 BGR 色彩空间。
YUV 直方图均衡化的例子如下:
import cv2 import numpy as np #OpenCV默认用BGR格式加载图像,因此需要先将其从BGR转换为YUV img = cv2.imread("test.jpg", 1) #读取图像 #用cv2.cvtColor函数将图像色彩空间转换为YCrCb imgYUV = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)#imgYUV存放转换后的结果图像 cv2.imshow("src", img) #显示原图像 channelsYUV = cv2.split(imgYUV) #拆分图像通道 channelsYUV=list(channelsYUV) #更改为列表类型 channelsYUV[0] = cv2.equalizeHist(channelsYUV[0]) #对Y通道进行均衡化 channels = cv2.merge(channelsYUV) #合并图像通道 #转换色彩空间为BGR,这样能够正确显示图像 result = cv2.cvtColor(channels, cv2.COLOR_YCrCb2BGR) cv2.imshow("dst", result) #显示图像 cv2.waitKey(0)在上述代码中,首先使用 cvtColor 函数将彩色图像转换到 YUV 颜色空间。然后,使用 cv::split() 函数分离通道,并对 Y 通道进行自适应均衡化处理。最后,使用 merge 函数合并通道,并将图像转换回 BGR 颜色空间。
要均衡 Y 通道,需先分解出通道,然后均衡化,最后合并通道。OpenCV 提供了一个 split 方法,直接传入图片就可以分离通道。
均衡化后,要将均衡化后的三个通道合并为一张彩色图片,这时需要使用 merge 方法。merge 方法将三个通道传入其中作为参数,返回的结果就是合并后的彩色图像值。
运行工程,结果如下图所示:

可以看出,均衡化后的图像的亮度和对比度增强了,但颜色没有变得特别鲜艳。因此只对 Y 通道进行均衡化,效果更好。