大部分攝像頭的數據輸出格式都是YUV格式,而YUV422是比較常見的一種。在Linux下通過攝像頭獲取圖片數據並壓縮為jpg格式的圖片,使用libjpeg這個庫,但貌似不能直接壓縮YUV數據,需要經過一些轉換,這里先將YUV轉換為RGB格式再送給libjpeg進行壓縮。
下面是YUV422轉RGB24的代碼:
1 int convert_yuv_to_rgb_pixel(int y, int u, int v) 2 { 3 unsigned int pixel32 = 0; 4 unsigned char *pixel = (unsigned char *)&pixel32; 5 int r, g, b; 6 r = y + (1.370705 * (v-128)); 7 g = y - (0.698001 * (v-128)) - (0.337633 * (u-128)); 8 b = y + (1.732446 * (u-128)); 9 if(r > 255) r = 255; 10 if(g > 255) g = 255; 11 if(b > 255) b = 255; 12 if(r < 0) r = 0; 13 if(g < 0) g = 0; 14 if(b < 0) b = 0; 15 pixel[0] = r ; 16 pixel[1] = g ; 17 pixel[2] = b ; 18 return pixel32; 19 } 20 21 int convert_yuv_to_rgb_buffer(unsigned char *yuv, unsigned char *rgb, unsigned int width, unsigned int height) 22 { 23 unsigned int in, out = 0; 24 unsigned int pixel_16; 25 unsigned char pixel_24[3]; 26 unsigned int pixel32; 27 int y0, u, y1, v; 28 29 for(in = 0; in < width * height * 2; in += 4) 30 { 31 pixel_16 = 32 yuv[in + 3] << 24 | 33 yuv[in + 2] << 16 | 34 yuv[in + 1] << 8 | 35 yuv[in + 0]; 36 y0 = (pixel_16 & 0x000000ff); 37 u = (pixel_16 & 0x0000ff00) >> 8; 38 y1 = (pixel_16 & 0x00ff0000) >> 16; 39 v = (pixel_16 & 0xff000000) >> 24; 40 pixel32 = convert_yuv_to_rgb_pixel(y0, u, v); 41 pixel_24[0] = (pixel32 & 0x000000ff); 42 pixel_24[1] = (pixel32 & 0x0000ff00) >> 8; 43 pixel_24[2] = (pixel32 & 0x00ff0000) >> 16; 44 rgb[out++] = pixel_24[0]; 45 rgb[out++] = pixel_24[1]; 46 rgb[out++] = pixel_24[2]; 47 pixel32 = convert_yuv_to_rgb_pixel(y1, u, v); 48 pixel_24[0] = (pixel32 & 0x000000ff); 49 pixel_24[1] = (pixel32 & 0x0000ff00) >> 8; 50 pixel_24[2] = (pixel32 & 0x00ff0000) >> 16; 51 rgb[out++] = pixel_24[0]; 52 rgb[out++] = pixel_24[1]; 53 rgb[out++] = pixel_24[2]; 54 } 55 return 0; 56 57 }
使用時,調用convert_yuv_to_rgb_buffer()這個函數就可以了。關於這個函數的參數解釋如下:
yuv:YUV422數據的起始地址
rgb:轉換后的數據的起始地址
width:攝像頭采集數據時所設置的圖片寬度(如:320)
height:攝像頭采集數據時所設置的圖片高度(如:240)