定义
百度百科定义:YUV是一种颜色编码方法.
“Y”表示明亮度(Luminance或Luma),也就是灰阶值,“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。
转换
转换需要注意的是,不同的色域,转换矩阵有差异。
数字RGB转YUV的推导公式:
W
r
+
W
g
+
W
b
=
1.0
.
W_r+W_g+W_b=1.0\,.
Wr+Wg+Wb=1.0.
U
m
a
x
=
0.5
,
V
m
a
x
=
0.5
.
U_{max}=0.5\,,V_{max}=0.5\,.
Umax=0.5,Vmax=0.5.
Y
=
W
r
∗
R
+
W
g
∗
G
+
W
b
∗
B
Y=W_r*R+W_g*G+W_b*B
Y=Wr∗R+Wg∗G+Wb∗B
U
=
U
m
a
x
∗
(
B
−
Y
)
/
(
1
−
W
b
)
U=U_{max}*(B-Y)/(1-W_b)
U=Umax∗(B−Y)/(1−Wb)
V
=
V
m
a
x
∗
(
R
−
Y
)
/
(
1
−
W
r
)
V=V_{max}*(R-Y)/(1-W_r)
V=Vmax∗(R−Y)/(1−Wr)
B
T
601
:
W
r
=
0.299
W
g
=
0.587
W
b
=
0.114
BT601:Wr = 0.299 Wg = 0.587 Wb = 0.114
BT601:Wr=0.299Wg=0.587Wb=0.114
B
T
709
:
W
r
=
0.2126
W
g
=
0.7152
W
b
=
0.0722
BT709:Wr = 0.2126 Wg = 0.7152 Wb = 0.0722
BT709:Wr=0.2126Wg=0.7152Wb=0.0722
B
T
2020
:
W
r
=
0.2627
W
g
=
0.678
W
b
=
0.0593
BT2020:Wr = 0.2627 Wg = 0.678 Wb = 0.0593
BT2020:Wr=0.2627Wg=0.678Wb=0.0593
HLSL 实现
void yuv2rgb(in float3 yuv, out float3 rgb)
{
float3x3 YUV2RGB601 =
{
1.0, 1.0, 1.0,
0.0, -0.344136289624630, 1.77200,
1.40200, -0.714136289624630, 0.0
};
float3x3 YUV2RGB709 =
{
1.0, 1.0, 1.0,
0.0, -0.187326980708465, 1.855601144893016,
1.574803149606299, -0.468124602462383, 0.0
};
float3x3 YUV2RGB601Full =
{
1.164383561643836, 1.164383561643836, 1.164383561643836,
0.0, -0.392, 2.017,
1.596, -0.813, 0.0
};
float3x3 YUV2RGB709Full =
{
1.164383561643836, 1.164383561643836, 1.164383561643836,
0.0, -0.21324861427373, 2.112401785714286,
1.792741071428571, -0.532909328559444f, 0.0
};
float3x3 YUV2RGBMat =
{
1, 1, 1,
0, -0.1873, 1.8556,
1.5748, -0.46807, 0
};
rgb = mul(float3(yuv.r, yuv.g - 0.5, yuv.b - 0.5), YUV2RGBMat);
}
void rgb2yuv(in float3 rgb, out float3 yuv)
{
float3x3 RGB2YUVMat =
{
0.2126, -0.11457, 0.5000,
0.7152, -0.38543, -0.45415,
0.0722, 0.5000, -0.04585
};
yuv = mul(rgb, RGB2YUVMat) + float3(0.0, 0.5, 0.5);
}
GLSL 实现
void yuvSample(out vec4 texColor, in vec2 texCoord)
{
vec3 yuv;
vec3 rgb;
yuv.x = texture2D(u_Texture0, texCoord).r;
yuv.y = texture2D(u_Texture1, texCoord).r - 0.5;
yuv.z = texture2D(u_Texture2, texCoord).r - 0.5;
rgb = mat3(1, 1, 1,
0, -0.3455, 1.779,
1.4075, -0.7169, 0) * yuv;
texColor = vec4(rgb, f_transparency);
}