通通透透VFW视频采集

     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;  
  }  
 

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值