通通透透VFW視頻採集

來源:互聯網
上載者:User

     VFW採集到視訊框架時

 

     1. 如果網路攝影機採用的是RGB24輸出的時候,在buffer中RGB三分量的排列順序是 [B0,G0,R0,B1,G1,R1....Bn,Gn,Rn] ,可以直接採用StretchDIBits來畫圖,但是在畫圖前必須填充BITMAPINFO 資訊結構體。該結構體中的內容可以從 VFW函數庫中capCaptureGetSetup函數來取得一部分資訊。

    2. 如果網路攝影機採用的是YUY2輸出的話,因為StretchDIBits函數只能採用RGB的色彩空間,所以必須首先轉換成RGB的資料。此時vfw回調所得buffer中的資料排列如下 [Y0 U0 Y1 V0 Y2 U1 Y3 V1] 轉換函式如下

/*
每連續的4個YUV,代表2個像素 UV是共用的
1. Y0 U0 Y1 V0 ===> [Y0 U0 V0][Y1 U0 V0] 代表兩個像素 
*/
void YUY2_RGB2(BYTE *YUY2buff,BYTE *RGBbuff,DWORD dwSize)
{
//
//C = Y - 16
//D = U - 128
//E = V - 128
//R = clip(( 298 * C           + 409 * E + 128) >> 8)
//G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
//B = clip(( 298 * C + 516 * D           + 128) >> 8)
     BYTE *orgRGBbuff = RGBbuff;
     for( DWORD count = 0; count < dwSize; count += 4 )
     {
          //Y0 U0 Y1 V0
          BYTE Y0 = *YUY2buff;
          BYTE U  = *(++YUY2buff);
          BYTE Y1 = *(++YUY2buff);
          BYTE V  = *(++YUY2buff);
          ++YUY2buff;

          LONG Y,C,D,E;
          BYTE R,G,B;

          Y = Y0;
          C = Y - 16;
          D = U - 128;
          E = V - 128;
          R = clip255(( 298 * C           + 409 * E + 128) >> 8);
          G = clip255(( 298 * C - 100 * D - 208 * E + 128) >> 8);
          B = clip255(( 298 * C + 516 * D           + 128) >> 8);

          *(RGBbuff)   = B;
          *(++RGBbuff) = G;
          *(++RGBbuff) = R;

          Y = Y1;
          C = Y-16;
          D = U-128;
          E = V-128;
          R = clip255(( 298 * C           + 409 * E + 128) >> 8);
          G = clip255(( 298 * C - 100 * D - 208 * E + 128) >> 8);
          B = clip255(( 298 * C + 516 * D           + 128) >> 8);
          *(++RGBbuff) = B;
          *(++RGBbuff) = G;
          *(++RGBbuff) = R;
          ++RGBbuff;

     }
}
BYTE clip255(LONG v)
{
     if(v < 0) v=0;
     else if( v > 255) v=255;
     return (BYTE)v;
}

 

YUV轉換後,如果要調用StretchDIBits來畫圖的話,傳入的buffer中的RGB分量的排列順序也必須按照BGR的順序,否則就會看到色彩顛倒的情況,所以上面的轉換函式也採用BGR的排列順序來排列順序。

 

   3.如果網路攝影機輸出的是RGB16的資料,我們只要StretchDIBits畫圖的時候設定位元影像屬性和輸出屬性一致就OK

 

如果要實現自己通過SetPiexel來畫像素的話,就必須把RGB16(RGB555,RGB565)擴大到RGB24(RGB888)

擴充公式如下

這裡的source就是RGB16(RGB555)

void  CDib::ConvertLine16To24_555(BYTE   *target,   BYTE   *source,   int   width_in_pixels)
{
   WORD   *bits   =   (WORD   *)source;  
   
  for   (int   cols   =   0;   cols   <   width_in_pixels;   cols++)  
  {  
   target[0]   =   (((bits[cols]   &   0x7C00)   >>   10)   *   0xFF)   /   0x1F;  
   target[1]   =   (((bits[cols]   &   0x03E0)   >>   5)   *   0xFF)   /   0x1F;  
   target[2]   =   (((bits[cols]   &   0x001F)   >>   0)   *   0xFF)   /   0x1F;  
   
   target   +=   3;  
  }  
 

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.