YUV格式具有亮度信息和 {MOD}彩信息分离的特点,但大多数图像处理操作都是基于RGB格式。
因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式。
RGB与YUV的变换公式如下:
YUV(256 级别) 可以从8位 RGB 直接计算:
Y = 0.299 R + 0.587 G + 0.114 B
U = - 0.1687 R - 0.3313 G + 0.5 B + 128
V = 0.5 R - 0.4187 G - 0.0813 B + 128
反过来,RGB 也可以直接从YUV (256级别) 计算:
R = Y + 1.402 (Cr-128)
G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
B = Y + 1.772 (Cb-128)
YUV格式比较多,下面以YV12格式为例,说明YV12格式转化成RGB24格式的方法。
其基本思路是按照RGB与YUV的变换公式进行逐像素的计算,但具体实现过程中,优化方法和技巧影响最终的转换效率。
说明:为了方便查看转换后的结果,在实现过程中,是BGR24格式代替RGB24格式,其转换过程是不变。
1. 基本实现
按照YUV与RGB的变换公式,逐像素访问Y、U、V分量的值,并转换成RGB。
bool YV12ToBGR24_Native(unsigned
char* pYUV,unsigned
char* pBGR24,
int width,
int height)
{
if (width <
1 || height <
1 || pYUV == NULL || pBGR24 ==
NULL)
return false;
const long len = width *
height;
unsigned char* yData =
pYUV;
unsigned char* vData = &
yData[len];
unsigned char* uData = &vData[len >>
2];
int bgr[
3];
int yIdx,uIdx,vIdx,idx;
for (
int i =
0;i < height;i++
){
for (
int j =
0;j < width;j++
){
yIdx = i * width +
j;
vIdx = (i/
2) * (width/
2) + (j/
2);
uIdx =
vIdx;
bgr[0] = (
int)(yData[yIdx] +
1.732446 * (uData[vIdx] -
128));
// b分量
bgr[
1] = (
int)(yData[yIdx] -
0.698001 * (uData[uIdx] -
128) -
0.703125 * (vData[vIdx] -
128));
// g分量
bgr[
2] = (
int)(yData[yIdx] +
1.370705 * (vData[uIdx] -
128));
// r分量
for (
int k =
0;k <
3;k++
){
idx = (i * width + j) *
3 +
k;
if(bgr[k] >=
0 && bgr[k] <=
255)
pBGR24[idx] =
bgr[k];
else
pBGR24[idx] = (bgr[k] <
0)?
0:
255;
}
}
}
return true;
}
2. 基于查表法的实现
逐一访问像素,进行浮点运算,比较耗时,因而
利用空间换时间思路,以查找表来替代转换过程中的一些计算。
优化过程可参考:
http://blog.csdn.net/colorant/article/details/1913162/
static int Table_fv1[
256] = { -
180, -
179, -
177, -
176, -
174, -
173, -
172, -
170, -
169, -
167, -
166, -
165, -
163, -
162, -
160, -
159, -
158, -
156, -
155, -
153, -
152, -
151, -
149, -
148, -
146, -
145, -
144, -
142, -
141, -
139, -
138, -
137, -
135, -
134, -
132, -
131, -
130, -
128, -
127, -
125, -
124, -
123, -
121, -
120, -
118, -
117, -
115, -
114, -
113, -
111, -
110, -
108, -
107, -
106, -
104, -
103, -
101, -
100, -
99, -
97, -
96, -
94, -
93, -
92, -
90, -
89, -
87, -
86, -
85, -
83, -
82, -
80, -
79, -
78, -
76, -
75, -
73, -
72, -
71, -
69, -
68, -
66, -
65, -
64,-
62, -
61, -
59, -
58, -
57, -
55, -
54, -
52, -
51, -
50, -
48, -
47, -
45, -
44, -
43, -
41, -
40, -
38, -
37, -
36, -
34, -
33, -
31, -
30, -
29, -
27, -
26, -
24, -
23, -
22, -
20, -
19, -
17, -
16, -
15, -
13, -
12, -
10, -
9, -
8, -
6, -
5, -
3, -
2,
0,
1,
2,
4,
5,
7,
8,
9,
11,
12,
14,
15,
16,
18,
19,
21,
22,
23,
25,
26,
28,
29,
30,
32,
33,
35,
36,
37,
39,
40,
42,
43,
44,
46,
47,
49,
50,
51,
53,
54,
56,
57,
58,
60,
61,
63,
64,
65,
67,
68,
70,
71,
72,
74,
75,
77,
78,
79,
81,
82,
84,
85,
86,
88,
89,
91,
92,
93,
95,
96,
98,
99,
100,
102,
103,
105,
106,
107,
109,
110,
112,
113,
114,
116,
117,
119,
120,
122,
123,
124,
126,
127,
129,
130,
131,
133,
134,
136,
137,
138,
140,
141,
143,
144,
145,
147,
148,
150,
151,
152,
154,
155,
157,
158,
159,
161,
162,
164,
165,
166,
168,
169,
171,
172,
173,
175,
176,
178 };
static int Table_fv2[
256] = { -
92, -
91, -
91, -
90, -
89, -
88, -
88, -
87, -
86, -
86, -
85, -
84, -
83, -
83, -
82, -
81, -
81, -
80, -
79, -
78, -
78, -
77, -
76, -
76, -
75, -
74, -
73, -
73, -
72, -
71, -
71, -
70, -
69, -
68, -
68, -
67, -
66, -
66, -
65, -
64, -
63, -
63, -
62, -
61, -
61, -
60, -
59, -
58, -
58, -
57, -
56, -
56, -
55, -
54, -
53, -
53, -
52, -
51, -
51, -
50, -
49, -
48, -
48, -
47, -
46, -
46, -
45, -
44, -
43, -
43, -
42, -
41, -
41, -
40, -
39, -
38, -
38, -
37, -
36, -
36, -
35, -
34, -
33, -
33, -
32, -
31, -
31, -
30, -
29, -
28, -
28, -
27, -
26, -
26, -
25, -
24, -
23, -
23, -
22, -
21, -
21, -
20, -
19, -
18, -
18, -
17, -
16, -
16, -
15, -
14, -
13, -
13, -
12, -
11, -
11, -
10, -
9, -
8, -
8, -
7, -
6, -
6, -
5, -
4, -
3, -
3, -
2, -
1,
0,
0,
1,
2,
2,
3,
4,
5,
5,
6,
7,
7,
8,
9,
10,
10,
11,
12,
12,
13,
14,
15,
15,
16,
17,
17,
18,
19,
20,
20,
21,
22,
22,
23,
24,
25,
25,
26,
27,
27,
28,
29,
30,
30,
31,
32,
32,
33,
34,
35,
35,
36,
37,
37,
38,
39,
40,
40,
41,
42,
42,
43,
44,
45,
45,
46,
47,
47,
48,
49,
50,
50,
51,
52,
52,
53,
54,
55,
55,
56,
57,
57,
58,
59,
60,
60,
61,
62,
62,
63,
64,
65,
65,
66,
67,
67,
68,
69,
70,
70,
71,
72,
72,
73,
74,
75,
75,
76,
77,
77,
78,
79,
80,
80,
81,
82,
82,
83,
84,
85,
85,
86,
87,
87,
88,
89,
90,
90 };
static int Table_fu1[
256] = { -
44, -
44, -
44, -
43, -
43, -
43, -
42, -
42, -
42, -
41, -
41, -
41, -
40, -
40, -
40, -
39, -
39, -
39, -
38, -
38, -
38, -
37, -
37, -
37, -
36, -
36, -
36, -
35, -
35, -
35, -
34, -
34, -
33, -
33, -
33, -
32, -
32, -
32, -
31, -
31, -
31, -
30, -
30, -
30, -
29, -
29, -
29, -
28, -
28, -
28, -
27, -
27, -
27, -
26, -
26, -
26, -
25, -
25, -
25, -
24, -
24, -
24, -
23, -
23, -
22, -
22, -
22, -
21, -
21, -
21, -
20, -
20, -
20, -
19, -
19, -
19, -
18, -
18, -
18, -
17, -
17, -
17, -
16, -
16, -
16, -
15, -
15, -
15, -
14, -
14, -
14, -
13, -
13, -
13, -
12, -
12, -
11, -
11, -
11, -
10, -
10, -
10, -
9, -
9, -
9, -
8, -
8, -
8, -
7, -
7, -
7, -
6, -
6, -
6, -
5, -
5, -
5, -
4, -
4, -
4, -
3, -
3, -
3, -
2, -
2, -
2, -
1, -
1,
0,
0,
0,
1,
1,
1,
2,
2,
2,
3,
3,
3,
4,
4,
4,
5,
5,
5,
6,
6,
6,
7,
7,
7,
8,
8,
8,
9,
9,
9,
10,
10,
11,
11,
11,
12,
12,
12,
13,
13,
13,
14,
14,
14,
15,
15,
15,
16,
16,
16,
17,
17,
17,
18,
18,
18,
19,
19,
19,
20,
20,
20,
21,
21,
22,
22,
22,
23,
23,
23,
24,
24,
24,
25,
25,
25,
26,
26,
26,
27,
27,
27,
28,
28,
28,
29,
29,
29,
30,
30,
30,
31,
31,
31,
32,
32,
33,
33,
33,
34,
34,