一:目的意义
在某些图像、视频中,经过一些图像处理之后,计算机对于处理后的图像仍然不能直白的检测出所需要的信息,这时候需要对某类色彩进行处理,使得所需要的信息更能直观的在处理后的图像显示出来。
二:RGB、YCBCR简介及公式转化
RGB:R:red(红色通道);G:green(绿色通道);B:blue(蓝色通道),三种颜色的叠加可以得到人类视力所能感知的所有颜色。
YCBCR:Y表示颜色的明亮度和浓度,也可叫灰度阶。(通过RGB转换YCBCR提取Y分量也可以得到灰度图像)
Cb:表示颜色的蓝色浓度偏移量即RGB输入信号蓝色部分与RGB信号亮度值之间的差异。
Cr:表示颜色的红色浓度偏移量即RGB输入信号红色部分与RGB信号亮度值之间的差异。
二者转换,可以将亮度和色度分离开,更直白的看到自己所需要图像。
二者相互转换公式:
1、RGB转YCBCR
Y=0.257*R+0.564*G+0.098*B+16
Cb=-0.148*R-0.291*G+0.439*B+128
Cr=0.439*R-0.368*G-0.071*B+128
2、YCBCR转RGB
R=1.164*(Y-16)+1.596*(Cr-128)
G=1.164*(Y-16)-0.392*(Cb-128)-0.813*(Cr-128)
B=1.164*(Y-16)+2.017*(Cb-128)
三:代码及运行效果
import numpy as np #存储处理大型矩阵
import imageio
import matplotlib.pyplot as plt # plt 用于显示图片
import cv2
lena = imageio.imread("lena.jpg")
plt.subplot(131)
plt.imshow(lena) # 显示图片
plt.axis('on') # 显示坐标轴
def rgb2ycbcr(rgb_image):
"""convert rgb into ycbcr"""
if len(rgb_image.shape)!=3 or rgb_image.shape[2]!=3:
raise ValueError("input image is not a rgb image")
rgb_image = rgb_image.astype(np.float32)
# 1:创建变换矩阵,和偏移量
transform_matrix = np.array([[0.257, 0.564, 0.098],
[-0.148, -0.291, 0.439],
[0.439, -0.368, -0.071]])
shift_matrix = np.array([16, 128, 128])
ycbcr_image = np.zeros(shape=rgb_image.shape)
w, h, _ = rgb_image.shape
# 2:遍历每个像素点的三个通道进行变换
for i in range(w):
for j in range(h):
ycbcr_image[i, j, :] = np.dot(transform_matrix, rgb_image[i, j, :]) + shift_matrix
return ycbcr_image
#opencv标准库的转换效果
ycrcb_image = cv2.cvtColor(lena, cv2.COLOR_RGB2YCR_CB)
lena_1 = rgb2ycbcr(lena)
plt.subplot(132)
plt.imshow(lena_1.astype(np.uint8)) # 显示图片
plt.axis('on') # 不显示坐标轴
plt.subplot(133)
plt.imshow(ycrcb_image)
plt.axis('on') # 显示坐标轴
plt.show()
左一为RGB原图,中间是转换为YCBCR的图像,
右一是通过opencv提供的标准库效果转换为YCRCB的图像
用公式计算转换的ycbcr图像与opencv标准库效果转换的图像基本一致,可以将上述代码矩阵的第二行与第三行换一下位置即可。