实验思路:1.原始的rgb格式图像,经过转换公式转换得到yuv格式图像的参数,然后4:2:0下采样得到yuv图像;2.yuv图像经过转换公式得到rgb图像的参数,经过4:4:4的上变换得到新的rgb图像;3.新的rgb格式图像,也经过转换公式转换得到yuv格式图像的参数,然后再4:2:0下采样得到新的yuv图像;4.新的yuv图像与第一步得到的yuv图像比较,观察不同。(经过上下变换后坑定会产生不同,但肉眼很难发现不同。)
1.彩色空间转换的基本思想及转换公式
(1)YUV与RGB空间的相互转换
由电视原理可知,亮度和色差信号的构成如下:
Y=0.2990R+0.5870G+0.1140B R-Y=0.7010R-0.5870G-0.1140B B-Y=-0.2990R-0.5870G+0.8860B
为了使色差信号的动态范围控制在0.5之间,需要进行归一化,对色差信号引入压缩系数。归一化后的色差信号为: U=-0.1684R-0.3316G+0.5B
V=0.5R-0.4187G-0.0813B
(2)码电平分配及数字表达式
l 亮电平信号量化后码电平分配 在对分量信号进行8比特均匀量化时,共分为256个等间隔的量化级。为了防止信号变动造成过载,在256级上端留20级,下端留16级作为信号超越动态范围的保护带。
1
l 色差信号量化后码电平分配 色差信号经过归一化处理后,动态范围为-0.5-0.5,让色差零电平对应码电平128,色差信号总共占225个量化级。在256级上端留15级,下端留16级作为信号超越动态范围的保护带。
(3)色度格式
4:2:0格式是指色差信号U,V的取样频率为亮度信号取样频率的四分之一,在水平方向和垂直方向上的取样点数均为Y的一半。
代码如下:
for (i = 0; i < size; i++)
{
g = b + 1;
r = b + 2;
tmp = (RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
if (tmp - 255>0)
*y = 255;
else *y = (unsigned char)(RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
tmp = (-RGBYUV01684[*r] - RGBYUV03316[*g] + (*b) / 2 + 128);
if (tmp - 255>0)
*u = 255;
else if (tmp<0)
*u = 0;
else *u = (unsigned char)(-RGBYUV01684[*r] - RGBYUV03316[*g] + (*b) / 2 + 128);
tmp = ((*r) / 2 - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
if (tmp - 255>0)
*v = 255;
else if (tmp<0)
*v = 0;
else *v = (unsigned char)((*r) / 2 - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
b += 3;
y++;
u++;
v++;
}
}
// subsample UV
for (j = 0; j < y_dim / 2; j++)
{
psu = sub_u_buf + j * x_dim / 2;
psv = sub_v_buf + j * x_dim / 2;
pu1 = u_buffer + 2 * j * x_dim;
pu2 = u_buffer + (2 * j + 1) * x_dim;
pv1 = v_buffer + 2 * j * x_dim;
pv2 = v_buffer + (2 * j + 1) * x_dim;
for (i = 0; i < x_dim / 2; i++)
{
*psu = (*pu1 + *(pu1 + 1) + *pu2 + *(pu2 + 1)) / 4;
*psv = (*pv1 + *(pv1 + 1) + *pv2 + *(pv2 + 1)) / 4;
psu++;
psv++;
pu1 += 2;
pu2 += 2;
pv1 += 2;
pv2 += 2;
}
}
free(u_buffer);
free(v_buffer);
return 0;
}
(4)yuv2rgb转换原理
经过计算得到转换方程RGB⎤⎦⎥=⎡⎣⎢1.00001.00001.00000.0000−0.34411.77181.4020−0.7139−0.0013⎤⎦⎥⎡⎣⎢YUV⎤⎦⎥+⎡⎣⎢−179.4497135.4193−226.6286⎤⎦
⎥
需要注意的是在做转换之前先将yuv数据进行4:4:4上变换。
代码如下: