为什么不能直接对RGB图做直方图均衡化

描述

相信好多人在开始学习FPGA图像处理的时候都是接触的RGB转灰度图,Sobel图像检测,直方图均衡化这样的算法。

然后在做直方图均衡化的时候也是要先RGB转灰度,然后再对灰度图进行直方图均衡化,网上的课程也大多数都是这样做的,不知道大家会不会产生一个疑问就不能直接对RGB图做直方图均衡化吗?

首先说答案是不可以的。

我们来看看为什么。

先来看一段简单的代码:

 

img = cv2.imread(r'E:python_image_simpythonProjectsimimgimg.png')


equ = cv2.equalizeHist(img)


cv2.imshow('bgr', img)
cv2.waitKey()
cv2.destroyAllWindows()

 

读取一张图片,然后对其做直方图均衡化,很简单,但是OpenCV报错了。

RGB

报错说直方图均衡化这个函数的参数应该是CV_8UC1,那么我们将RGB通道给分离出来分别进行直方图均衡化不就好了吗,说干就干。

 

img = cv2.imread(r'E:python_image_simpythonProjectsimimgimg.png')


b, g, r = cv2.split(img)
equ_b = cv2.equalizeHist(b)
equ_g = cv2.equalizeHist(g)
equ_r = cv2.equalizeHist(r)
equ = cv2.merge([equ_b, equ_g, equ_r])
cv2.imshow('bgr', img)
cv2.imshow('bgr_equ', equ)
cv2.waitKey()
cv2.destroyAllWindows()

 

上述代码将BGR通道进行了分离,然后分别进行直方图均衡化,最后再将结果给合并起来。

ps:opencv读取的图片默认是BGR格式的,而不是RGB格式的。

来看看效果吧。

 

 

一个原图,一个效果图,可以发现效果很差,把我们原先的色彩都给打乱了。特别是图像的上半部分直接颜色都变了。

那么这是为啥呢。

这个就需要了解一下什么是色彩空间了。

色彩是一种感性的认识,科学家们为了去表示色彩就发明了许多的色彩空间,比如RGB,YUV,HSV,HSI,HSL等多种表示方式,每一种使用范围也不太一样。

比如RGB色彩空间把图像用红色,绿色,蓝色来表示,但是这种色彩空间把图像的亮度和色度混在了一起进行表示,也就是不区分luma 和chroma 的值,这样在对其中某一个进行变换的时候就会把另外一个也进行了变换。比如在进行直方图均衡化的时候是对luma进行操作的,由于RGB混在一起的表示形式就会把chroma也给搞乱掉,这样就表现出来了上图的效果。

如果是对图像进行线性变换的话还能恢复过来,如果是非线性的变化那岂不是搞不回来了,把另外一个彻底搞乱掉了。

而YUV色彩空间用Y来表示亮度,用UV表示色度,这样单独对Y通道进行直方图均衡化就可以了,不会对色度产生影响。

 

import cv2


img = cv2.imread(r'E:python_image_simpythonProjectsimimgimg.png')


y, u, v = cv2.split(cv2.cvtColor(img, cv2.COLOR_BGR2YUV))


b, g, r = cv2.split(img)
equ_b = cv2.equalizeHist(b)
equ_g = cv2.equalizeHist(g)
equ_r = cv2.equalizeHist(r)
equ_y = cv2.equalizeHist(y)
yuv = cv2.merge([equ_y, u, v])
yuv = cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR)


equ = cv2.merge([equ_b, equ_g, equ_r])


# stacking images side-by-side
cv2.imshow('rgb', img)
cv2.imshow('bgr_equ', equ)
cv2.imshow('yuv_equ', yuv)
cv2.waitKey()
cv2.destroyAllWindows()









 

上述代码将BGR色彩空间转为YUV,然后对Y通道进行直方图均衡化,最后再转回BGR色彩空间。

来看看效果图。

 

直方图均衡化后比直接RGB直方图的效果要好很多。

 

最后这个对比图是通过matplotlib画出来的,需要注意的是matplotlib默认是RGB模式的,所以需要将BGR转为RGB才能正常显示出来。

 

import matplotlib.pyplot as plt


img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
equ = cv2.cvtColor(equ, cv2.COLOR_BGR2RGB)
yuv = cv2.cvtColor(yuv, cv2.COLOR_BGR2RGB)
plt.figure()
plt.subplot(1, 3, 1)
plt.imshow(img)
plt.title("img")
plt.subplot(1, 3, 2)
plt.imshow(equ)
plt.title("bgr_equ")
plt.subplot(1, 3, 3)
plt.title("yuv_euq")
plt.imshow(yuv)


plt.show()

 

  审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分