相信好多人在开始学习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报错了。
报错说直方图均衡化这个函数的参数应该是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()
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !