OpenCV中YUV颜色空间变换到RGB颜色空间采用的公式如下:
浮点:
{
R
=
1.164
(
Y
−
16
)
+
1.596
(
V
−
128
)
G
=
1.164
(
Y
−
16
)
−
0.813
(
V
−
128
)
−
0.391
(
U
−
128
)
B
=
1.164
(
Y
−
16
)
+
2.018
(
U
−
128
)
\footnotesize \begin{cases} R=1.164(Y-16)+1.596(V-128) \\ G=1.164(Y-16) -0.813(V-128)-0.391(U-128) \\ B = 1.164(Y-16)+2.018(U-128) \end{cases}
⎩⎨⎧R=1.164(Y−16)+1.596(V−128)G=1.164(Y−16)−0.813(V−128)−0.391(U−128)B=1.164(Y−16)+2.018(U−128) 整型:系数整体放大
2
20
2^{20}
220倍,并在变换到原始尺度时加入0.5用于四舍五入
{
R
=
(
1220542
(
Y
−
16
)
+
1673527
(
V
−
128
)
+
(
1
<
<
19
)
)
>
>
20
G
=
(
1220542
(
Y
−
16
)
−
852492
(
V
−
128
)
−
409993
(
U
−
128
)
+
(
1
<
<
19
)
)
>
>
20
B
=
(
1220542
(
Y
−
16
)
+
2116026
(
U
−
128
)
+
(
1
<
<
19
)
)
>
>
20
\footnotesize \begin{cases} R=(1220542(Y-16)+1673527(V-128)+(1<<19)) >> 20 \\ G=(1220542(Y-16) -852492(V-128)-409993(U-128)+(1<<19)) >> 20 \\ B =(1220542(Y-16)+2116026(U-128)+(1<<19))>>20 \end{cases}
⎩⎨⎧R=(1220542(Y−16)+1673527(V−128)+(1<<19))>>20G=(1220542(Y−16)−852492(V−128)−409993(U−128)+(1<<19))>>20B=(1220542(Y−16)+2116026(U−128)+(1<<19))>>20
O
p
e
n
C
V
\footnotesize OpenCV
OpenCV中关键代码如下:
截取自
O
p
e
n
C
V
2.4.13
i
m
g
p
r
o
c
\footnotesize OpenCV 2.4.13 \ imgproc
OpenCV2.4.13 imgproc模块的
c
o
l
o
r
.
c
p
p
\footnotesize color.cpp
color.cpp文件
Y
U
V
420
→
R
G
B
\footnotesize YUV420 \rightarrow RGB
YUV420→RGB部分代码,大约为
3042
\footnotesize 3042
3042行左右。
/************************************代码开始********************************************/
const int ITUR_BT_601_CY = 1220542;
const int ITUR_BT_601_CUB = 2116026;
const int ITUR_BT_601_CUG = -409993;
const int ITUR_BT_601_CVG = -852492;
const int ITUR_BT_601_CVR = 1673527;
const int ITUR_BT_601_SHIFT = 20;
// u、v值分别先减去128
int u = int(uv[i + 0 + uIdx]) - 128;
int v = int(uv[i + 1 - uIdx]) - 128;
// int ruv=(1<<(20-1))+1673527*v
int ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * v;
// int guv=(1<<(20-1))-852492*v-409993*u
int guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * v + ITUR_BT_601_CUG * u;
// int buv = (1<<(20-1))+2116026*u
int buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * u;
// 使用(同一组uv、共用同一uv分量的y)根据公式做计算得到 RGB
int y00 = std::max(0, int(y1[i]) - 16) * ITUR_BT_601_CY;
row1[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> ITUR_BT_601_SHIFT); // R
row1[1] = saturate_cast<uchar>((y00 + guv) >> ITUR_BT_601_SHIFT); // G
row1[bIdx] = saturate_cast<uchar>((y00 + buv) >> ITUR_BT_601_SHIFT); // B
int y01 = std::max(0, int(y1[i + 1]) - 16) * ITUR_BT_601_CY;
row1[5-bIdx] = saturate_cast<uchar>((y01 + ruv) >> ITUR_BT_601_SHIFT); // R
row1[4] = saturate_cast<uchar>((y01 + guv) >> ITUR_BT_601_SHIFT); // G
row1[3+bIdx] = saturate_cast<uchar>((y01 + buv) >> ITUR_BT_601_SHIFT); // B
int y10 = std::max(0, int(y2[i]) - 16) * ITUR_BT_601_CY;
row2[2-bIdx] = saturate_cast<uchar>((y10 + ruv) >> ITUR_BT_601_SHIFT); // R
row2[1] = saturate_cast<uchar>((y10 + guv) >> ITUR_BT_601_SHIFT); // G
row2[bIdx] = saturate_cast<uchar>((y10 + buv) >> ITUR_BT_601_SHIFT); // B
int y11 = std::max(0, int(y2[i + 1]) - 16) * ITUR_BT_601_CY;
row2[5-bIdx] = saturate_cast<uchar>((y11 + ruv) >> ITUR_BT_601_SHIFT); // R
row2[4] = saturate_cast<uchar>((y11 + guv) >> ITUR_BT_601_SHIFT); // G
row2[3+bIdx] = saturate_cast<uchar>((y11 + buv) >> ITUR_BT_601_SHIFT); // B
/************************************代码结束********************************************/