0%

颜色空间转换RGB->YCbCr

RGB、YUV和YCbCr都是人为规定的彩色模型或颜色空间(有时也叫彩色系统或彩色空间)。它的用途是在某些标准下用通常可接受的方式对彩色加以说明。本质上,彩色模型是坐标系统和子空间的阐述。

YCbCr与RGB的相互转换

RGB->YCbCr

YCbCr->RGB

测试代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import matplotlib.pyplot as plt # plt 用于显示图片
import numpy as np
import cv2
import copy

# ITU-R BT.601
# https://en.wikipedia.org/wiki/YCbCr
# RGB -> YCbCr
def rgb2ycbcr(rgb):
m = np.array([[ 0.299, 0.587, 0.114],
[-0.1686, -0.3311, 0.4997],
[ 0.4998, -0.4185, -0.0813]])
shape = rgb.shape
if len(shape) == 3:
rgb = rgb.reshape((shape[0] * shape[1], 3))
ycbcr = np.dot(rgb, m.transpose())

return ycbcr.reshape(shape)

# ITU-R BT.601
# https://en.wikipedia.org/wiki/YCbCr
# YUV -> RGB
def ycbcr2rgb(ycbcr):
m = np.array([[ 1,0, 1.402],
[1, -0.344, -0.714],
[ 1, 1.772, 0]])
shape = ycbcr.shape
if len(shape) == 3:
ycbcr = ycbcr.reshape((shape[0] * shape[1], 3))
rgb = copy.deepcopy(ycbcr)
rgb = np.dot(ycbcr, m.transpose())
return rgb.reshape(shape)

def main():
#opencv的颜色通道顺序为[B,G,R],而matplotlib颜色通道顺序为[R,G,B],所以需要调换一下通道位置
img1 = cv2.imread('./yuv.jpg')[:,:,(2,1,0)] # 读取和代码处于同一目录下的 yuv.jpg
img2=rgb2ycbcr(img1)

#结果展示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 中文乱码
plt.subplot(221)
#imshow()对图像进行处理,画出图像,show()进行图像显示
plt.imshow(img1)
plt.title('RGB原图')
#不显示坐标轴
plt.axis('off')
# print('原RGB图像')
# print(img1)

#子图2
plt.subplot(222)
img2=rgb2ycbcr(img1)
#Cb分量赋值为0
img2[:,:,1]=0
#Cr分量赋值为0
img2[:,:,2]=0
#重新转成rgb图像
img3=ycbcr2rgb(img2)
# print('RGB-YCbCr图像')
# print(img2)
img3=img3.astype(np.uint8)
plt.imshow(img3)
plt.title('Y通道')
plt.axis('off')

#子图3
plt.subplot(223)
# print('YCbCr-RGB图像')
# print(img3)
img2=rgb2ycbcr(img1)
#Y分量赋值为0
img2[:,:,0]=0
#Cr分量赋值为0
img2[:,:,2]=0
#重新转成rgb图像
img4=ycbcr2rgb(img2)
# print(img4)
img4=img4.astype(np.uint8)
# print(img3)
plt.imshow(img4)
plt.title('Cb通道')
plt.axis('off')

#子图4
plt.subplot(224)
img2=rgb2ycbcr(img1)
#Y分量赋值为0
img2[:,:,0]=0
#Cb分量赋值为0
img2[:,:,1]=0
#重新转成rgb图像
img5=ycbcr2rgb(img2)
img5=img5.astype(np.uint8)
plt.imshow(img5)
plt.title('Cr通道')
plt.axis('off')

# #设置子图默认的间距
plt.tight_layout()
#显示图像
plt.show()


if __name__ =='__main__':
main()

运行结果

原图片

yuv

转换结果

ycbcr_split

参考

YCbCr

jpeg图片格式详解

RGB、YUV和HSV颜色空间模型

【整理】RGB和YUV色彩模式

YUV颜色编码格式

在Python中正确地将RGB转换成YCbCr

JPEG算法解密

------------- THE END! THANKS! -------------