YUV是視訊系統中常用的顔色空間,而顯示通常是按照RGB格式進行輸出顯示的,要使YUV資料格式能夠在顯示屏上顯示,需要将YUV格式轉換為RGB格式,下面給出了YUV422到RGB565顔色空間轉換的簡單描述和程式實作。
1. 轉換公式
YUV轉換為RGB的公式如下:
R = Y + 1.402*(V-128);
G = Y - 0.34414*(U-128) - 0.71414*(V-128);
B = Y + 1.772*(U-128);
為了便于在計算機系統中進行處理,我們對公式進行一下簡化:
R = Y + 1.402*(V-128) = y + v + 0.402*v = y + v + ((103 * v) >> 8);
G = Y - 0.34414*(U-128) - 0.71414*(V-128) = y - ((u * 88) >> 8) - ((v * 183) >> 8);
B = Y + 1.772*(U-128) = y + u + (u * 198) >> 8;
即:
R = y + v + ((103 * v) >> 8);
G = y - ((u * 88) >> 8) - ((v * 183) >> 8);
B = y + u + (u * 198) >> 8;
2. 程式實作
根據上面公式可以換算得到R、G、B三個分量數值,得到的數值需要經過範圍轉換以免越界導緻色彩失真。 程式實作如下:
#define RANGE_LIMIT(x) (x > 255 ? 255 : (x < 0 ? 0 : x))
void YUV422ToRGB565(const void* inbuf, void* outbuf, int width, int height)
{
int rows, cols;
int y, u, v, r, g, b;
unsigned char *yuv_buf;
unsigned short *rgb_buf;
int y_pos,u_pos,v_pos;
yuv_buf = (unsigned char *)inbuf;
rgb_buf = (unsigned short *)outbuf;
y_pos = 0;
u_pos = 1;
v_pos = 3;
for (rows = 0; rows < height; rows++) {
for (cols = 0; cols < width; cols++) {
y = yuv_buf[y_pos];
u = yuv_buf[u_pos] - 128;
v = yuv_buf[v_pos] - 128;
// R = Y + 1.402*(V-128)
// G = Y - 0.34414*(U-128)
// B = Y + 1.772*(U-128)
r = RANGE_LIMIT(y + v + ((v * 103) >> 8));
g = RANGE_LIMIT(y - ((u * 88) >> 8) - ((v * 183) >> 8));
b = RANGE_LIMIT(y + u + ((u * 198) >> 8));
*rgb_buf++ = (((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
y_pos += 2;
if (cols & 0x01) {
u_pos += 4;
v_pos += 4;
}
}
}
}
以上是YUV422(YUYV)轉為RGB565的實作,對于其他格式的YUV格式,如YUV420, YUV422P等格式的轉換,其實作都類似,主要的差別在于y, u, v分量的提取上,将程式做簡單的修改就能夠實作對應格式的YUV資料轉換為RGB565資料格式。