一般情况下我们都是将RGB图像转化为灰色图,很少将灰色图又转化为RGB图像。如果有所需求,将灰色图转化为RGB图像,但是,又发现网上很少有这方面的解答,一下子就会觉得无从下手。我使用opencv-python来解决这个问题。

       都知道opencv中有一个函数cvtcolor()中有一个参数cv2.COLOR_GRAY2BGR,它能直接将灰色图变换成RGB图像吗?

import numpy as np
import cv2
# 首先以灰色读取一张照片
src = cv2.imread("demo.jpg", 0)
# 然后用ctvcolor()函数,进行图像变换。
src_RGB = cv2.cvtColor(src, cv2.COLOR_GRAY2BGR)
# 显示图片
cv2.imshow("input", src)
cv2.imshow("output", src_RGB)
cv2.waitKey(0)
cv2.destroyAllWindows()

显示图片:


可以看出并没有什么改变的,还是灰色图像。那么怎么办?

        RGB图像中有三个维度的信息,每种颜色相当于一个三维向量,表示法则相当于同一个向量在不同的坐标轴下(即不同的基下)的表示。而将其变为灰度后,只剩下一个维度,相当于将三维向量投影为一维标量一样,是不可能回复为原来的向量的。要想恢复,就必须储存另外两个维度的信息,合在一起就是原先的三维向量,这就是原理。

那么怎么做?

       我们要将RGB表示转换为gGB表示,也就是用灰度分量g取代蓝色分量R,蓝色分量B和绿色分量G不变。我们可以从gGB计算出红色分量R,因为灰度g=p*R+q*G+t*B(其中p=0.2989,q=0.5870,t=0.1140),于是R=(g-q*G-t*B)/p。于是我们只要保留B和G两个颜色分量,再加上灰度图g,就可以回复原来的RGB图像。同样,我们这里的g是可以随便取代红绿蓝三种分量中的任一分量的。下面进行演示。

from __future__ import division
import numpy as np
import cv2
src = cv2.imread("C:/Users/12914/Pictures/messi.jpg")
src_gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# RGB在opencv中存储为BGR的顺序,数据结构为一个3D的numpy.array,索引的顺序是行,列,通道:
B = src[:,:,0]
G = src[:,:,1]
R = src[:,:,2]
# 灰度g=p*R+q*G+t*B(其中p=0.2989,q=0.5870,t=0.1140),于是B=(g-p*R-q*G)/t。于是我们只要保留R和G两个颜色分量,再加上灰度图g,就可以回复原来的RGB图像。
g = src_gray[:]
p = 0.2989; q = 0.5870; t = 0.1140
B_new = (g-p*R-q*G)/t
B_new = np.uint8(B_new)
src_new = np.zeros((src.shape)).astype("uint8")
src_new[:,:,0] = B_new
src_new[:,:,1] = G
src_new[:,:,2] = R
# 显示图像
cv2.imshow("input", src)
cv2.imshow("output", src_gray)
cv2.imshow("result", src_new)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像显示:



现在就可以看出“result”与“input”图像是一致的了吧。所以,仅通过cvtcolor()函数是没有办法将灰色图直接转化为RGB图像的。


Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐