2012-01-12 45 views
3

我正在使用video4linux編寫一個C++攝像頭查看器。我需要一個RGB24輸出(交織的R8B8G8)用於顯示。我可以使用YUYV,GREY8或RGB24爲幾乎所有低分辨率攝像頭獲取視頻輸入。但是我還需要從高分辨率網絡攝像機獲得輸入,當需要高幀率時,使用MJPEG進行壓縮。mjpeg到raw rgb24 with video4linux

我能夠使用V4L2_PIX_FMT_MJPEG作爲像素格式獲得MJPEG流,但收到的幀緩衝器已壓縮。

如何快速將其轉換爲RGB24?

我可以使用libjpeg嗎?

回答

2

我發現最快的解決辦法是decode_jpeg_raw從將jpeg數據解碼爲平面YUV420的mjpegtools。然後從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; 
    } 
} 
0

是的,你可以使用libjpeg,但通常libjpeg的輸出是YUV420或YUV422。 您可以改爲使用該代碼:http://mxhaard.free.fr/spca50x/Download/gspcav1-20071224.tar.gz(檢查解碼器源,還有一個與色彩轉換直接使輸出爲RGB888運作良好,交易的小JPEG解碼器)

+0

從YUV轉換爲RGB24是不是我的問題。謝謝,我正在嘗試你提供的代碼。 – 2012-01-12 15:06:19