![5a05055b08cef4178c80071cf512b541.png](https://i-blog.csdnimg.cn/blog_migrate/f096c8f14c70a589e0b242d105b92582.jpeg)
256256 OpenCV可以将彩色图转换成灰度图,这不难理解。但是OpenCV能将灰度图转换成彩色图,这也太厉害了吧。想象一下,将图1中的灰度图输入进去,出来的竟然是图2这种的彩色图,也太不可思议了,可事实是我想多了。
![4bd48a284c7bc4908e22d6ab44bc5382.png](https://i-blog.csdnimg.cn/blog_migrate/048e97c1ef1a0079f411347c4d43218a.jpeg)
![be3567e5c4a047e6c3f7c199ce783401.png](https://i-blog.csdnimg.cn/blog_migrate/482aaadf4752a8693887108c68c9ed50.jpeg)
首先看看彩色图是怎么转换成灰度图的,先读入照片
import cv2
import numpy as np
img_rgb = cv2.imread(r'..imagelena_rgb.jpg')
这里采用了三种方式将RGB图像装换成灰度图。第一种是根据公式GRAY=0.3*R+0.59*G+0.11*B:
#第一种 GRAY=0.3*R+0.59*G+0.11*B
效果如下:
![4bd48a284c7bc4908e22d6ab44bc5382.png](https://i-blog.csdnimg.cn/blog_migrate/048e97c1ef1a0079f411347c4d43218a.jpeg)
第二种是对每个通道求均值:
#第二种 GRAY=(R+G+B)/3
img_gray2 = (img_rgb[:,:,0] + img_rgb[:,:,1] + img_rgb[:,:,2]) / 3
img_gray2 = img_gray2.astype(np.uint8)
效果如下:
![ca50da03dc8e35e13b5fa304fb5d55c4.png](https://i-blog.csdnimg.cn/blog_migrate/e3b0dc387b7aaa9ed72ae381c1017b58.jpeg)
可见效果并不好
第二种是取每个通道上的最大值:
#第三种 max(R,G,B)
img_gray3 = np.zeros((256,256))
for i in range(0,256):
for j in range(0,256):
img_gray3[i][j] = np.max((img_rgb[:,:,0][i][j], img_rgb[:,:,1][i][j], img_rgb[:,:,2][i][j]))
img_gray3 = img_gray3.astype(np.uint8)
效果如下:
![c21d47dad45be0d1310ee0d8d8e53c77.png](https://i-blog.csdnimg.cn/blog_migrate/f5413695af1f0e4d3f35dcf1e7a40379.jpeg)
可以看出,图片有点偏亮了,毕竟是选取的最大值
再来看看OpenCV是怎么转换的:
img_gray4 = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
效果如下:
![7a34abc87761f21b48c6e7d71d552798.png](https://i-blog.csdnimg.cn/blog_migrate/f0051770c961d9f2b3bdc79dc65dd4b3.jpeg)
看起来跟第一种GRAY=0.3*R+0.59*G+0.11*B的结果挺像的,来看看是不是这样实现的:
#两者相减,看值是否为0
sub = img_gray4 - img_gray
count, count1 = 0, 0
for i in range(sub.shape[0]):
for j in range(sub.shape[1]):
if(sub[i][j] == 0):
count += 1
elif(sub[i][j] == 1):
count1 += 1
图片的尺寸为256*256,因此sub也为256*256,共有65536个点,sub中的零值共38599个,值为1的共有26937个,加起来刚好是65536,也验证了OpenCV使用的这种转换方式,可能在计算精度上有点区别。
接下来就看看OpenCV是怎么讲灰度图转换成彩色图的,首先读入一张灰度图(就是刚刚保存的),注意应设置flags为0,代表输入的是灰度图。
img_gray = cv2.imread(r'..imagegray4.jpg', flags = 0)
然后将其转化成彩色图:
img2 = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
img2显示如下:
![e3b9a63e5c1feba26d81197e2659199a.png](https://i-blog.csdnimg.cn/blog_migrate/9bae6ac26e78cf6f7240fba72fa2cd87.jpeg)
是的,你没有看错,这就是转化后的彩色图,果然事实跟想象还是有差异的。接下来就分析下为什么是这个样子。先打印img2的shape看看,确保这是彩色图
print(img2.shape)
输出(256, 256, 3),可以确定这就是彩色图了。那它是如何转化的呢,我一开始的想法是:这应该是一个查表的操作,灰度图中的0-255每一个值都对应三个(R,G,B)的值,对应关系可以由某个公式计算出来。事实比这个还简单。我将每一个通道的值都跟原始灰度图做差,来看看结果如何。
sub1 = img2[:, :, 0] - img_gray
sub2 = img2[:, :, 1] - img_gray
sub3 = img2[:, :, 2] - img_gray
#判断sub中的每个值是不是都等于0
print((sub1 == 0).all())
print((sub2 == 0).all())
print((sub3 == 0).all())
输出的是True True True。很明显OpenCV就是把灰度图复制了三遍,分别赋值R,G,B三个通道。
那应该怎么理解呢,其实R,G,B三个通道上的值相等时,所呈现的颜色就是灰色(很容易验证),只有亮跟暗的区别,值越大就越亮,越小就越暗。也就是从灰度图中的亮度变成了彩色图中的灰色了。所以使用这个函数将灰度图转换成彩色图时,如果出现的还是黑白图,不要觉得是程序出错了。
(占个坑)将灰度图转换成五颜六色的彩色图可能需要深度学习来实现了,有机会再写。