我正在使用video4linux编写c ++网络摄像头查看器。我需要RGB24输出(交错 R8B8G8 )进行显示。我可以使用YUYV,GREY8或RGB24为几乎所有低分辨率网络摄像头获取视频输入。但我需要从高分辨率网络摄像头获得输入,当需要高帧率时,使用 MJPEG 进行压缩。
我能够使用V4L2_PIX_FMT_MJPEG
作为像素格式获取MJPEG流,但是接收到的帧缓冲是压缩的。
如何快速将其转换为RGB24?
我可以使用libjpeg吗?
答案 0 :(得分:2)
我发现最快的解决方案是来自mjpegtools的decode_jpeg_raw
,它将jpeg数据解码为平面YUV420。然后从yuv420到rgb24的转换由此函数完成:
inline int clip(int value) {
return (value > 255) ? 255 : (value < 0) ? 0 : value;
}
static void yuv420_to_rgb24(
/* luminance (source) */const uint8_t* const y
/* u chrominance (source) */, const uint8_t* u
/* v chrominance (source) */, const uint8_t* v
/* rgb interleaved (destination) */, uint8_t* const dst
/* jpeg size */, int const size
/* image width */, int const width) {
const int lineSize = width * 3;
uint8_t* r1 = dst;
uint8_t* g1 = r1 + 1;
uint8_t* b1 = r1 + 2;
uint8_t* r2 = r1 + lineSize;
uint8_t* g2 = r2 + 1;
uint8_t* b2 = r2 + 2;
const uint8_t* y1 = y;
const uint8_t* y2 = y + width;
uint8_t* const end = r1 + size;
int c1 = 0;
int c2 = 0;
int e = 0;
int d = 0;
while (r1 != end) {
uint8_t* const lineEnd = r2;
/* line by line */
while (r1 != lineEnd) {
/* first pixel */
c1 = *y1 - 16;
c2 = *y2 - 16;
d = *u - 128;
e = *v - 128;
*r1 = clip(c1 + ((454 * e) >> 8));
*g1 = clip(c1 - ((88 * e + 183 * d) >> 8));
*b1 = clip(c1 + ((359 * d) >> 8));
*r2 = clip(c2 + ((454 * e) >> 8));
*g2 = clip(c2 - ((88 * e + 183 * d) >> 8));
*b2 = clip(c2 + ((359 * d) >> 8));
r1 += 3;
g1 += 3;
b1 += 3;
r2 += 3;
g2 += 3;
b2 += 3;
++y1;
++y2;
/* second pixel */
c1 = *y1 - 16;
c2 = *y2 - 16;
d = *u - 128;
e = *v - 128;
*r1 = clip(c1 + ((454 * e) >> 8));
*g1 = clip(c1 - ((88 * e + 183 * d) >> 8));
*b1 = clip(c1 + ((359 * d) >> 8));
*r2 = clip(c2 + ((454 * e) >> 8));
*g2 = clip(c2 - ((88 * e + 183 * d) >> 8));
*b2 = clip(c2 + ((359 * d) >> 8));
r1 += 3;
g1 += 3;
b1 += 3;
r2 += 3;
g2 += 3;
b2 += 3;
++y1;
++y2;
++u;
++v;
}
r1 += lineSize;
g1 += lineSize;
b1 += lineSize;
r2 += lineSize;
g2 += lineSize;
b2 += lineSize;
y1 += width;
y2 += width;
}
}
答案 1 :(得分:0)
是的,你可以使用libjpeg,但通常libjpeg的输出是YUV420或YUV422。 您可能改为使用该代码:http://mxhaard.free.fr/spca50x/Download/gspcav1-20071224.tar.gz(检查解码器源,有一个小的jpeg解码器运行良好并直接处理颜色转换,因此输出在RGB888中)