大部分摄像头的数据输出格式都是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)