Convert RGB2YUV

    在图像处理过程中,很多场合需要对RGB图像进行YUV格式转换。主要由于YUV色彩空间的图像容易实现目标图像与阴影的分割(阴影的YUV数据存在跟目标图像的YUV数据存在明显的差异),另一种原因是YUV420格式的图片数据缩小了图片的大小,在大量的图片处理过程中,降低了内存的消耗,提高运行效率。
由于RGB和YUV图像数据都不是灰度图像,它们都由三种色彩组成。所以存储一张RGB和YUV格式的图像数据所需要的字节数都为图像的宽width*图像的高hight*3。

一、RGB

    RGB图像数据也有很多种,具体根据r、g、b三种色彩排列形式而分列。假设有一张分辨率为352*288的RGB图像,并把其对应的352列288行的二维像素矩阵转化为352*288列的一维像素阵。把按照

r1、g1、b1,r2、g2、b2,…,r352、g352、b352,…,r352*288、g352*288、b352*288
这样排列的RGB图像数据归列为[rgb]。像有些通过OPencv得到的RGB图像,它的排列方式就不是这样,它排列的方式为

[gbr]: g1、b1、r1,g2、b2、r2,…,g352、b352、r352,…,g352*288、b352*288、r352*288

所以在转化RGB图像之前先弄明白它的r、b、g是怎样排列的。

二、YUV

    YUV图像数据也一样,它的排列方式更多,所以有很多种YUV格式的数据

[yuv]: y1、u1、v1,y2、u2、v2,…,y352、u352、v352,…,y352*288、u352*288、v352*288
[y][u][v]:   y1、y2、y3、y4、…、y352*288,u1、u2、u3、……、u352*288/4,v1、v2、v3、…、v352*288/4
    第二种[y][u][v]排列方式就是YUV420数据格式,它是按照Y:U:V=4:1:1的数据量排列,所以它的字节数变为图像的宽width*图像的高hight*3/2,并且排列的方式为首先排列完所有的Y团块,其次是U团块,最后是V团块。

三、RGB[rbg] to YUV420([y][u][v])

#include  <string.h>
int RGB2YUV_YR[256], RGB2YUV_YG[256], RGB2YUV_YB[256]; 
int RGB2YUV_UR[256], RGB2YUV_UG[256], RGB2YUV_UBVR[256]; 
int RGB2YUV_VG[256], RGB2YUV_VB[256]; 
// Table used for RGB to YUV420 conversion 
void InitLookupTable() 
{ int i;
  for (i = 0; i < 256; i++) RGB2YUV_YR[i] = (float)65.481 * (i<<8);
  for (i = 0; i < 256; i++) RGB2YUV_YG[i] = (float)128.553 * (i<<8); 
  for (i = 0; i < 256; i++) RGB2YUV_YB[i] = (float)24.966 * (i<<8); 
  for (i = 0; i < 256; i++) RGB2YUV_UR[i] = (float)37.797 * (i<<8); 
  for (i = 0; i < 256; i++) RGB2YUV_UG[i] = (float)74.203 * (i<<8); 
  for (i = 0; i < 256; i++) RGB2YUV_VG[i] = (float)93.786 * (i<<8); 
  for (i = 0; i < 256; i++) RGB2YUV_VB[i] = (float)18.214 * (i<<8); 
  for (i = 0; i < 256; i++) RGB2YUV_UBVR[i] = (float)112 * (i<<8); 
}
// Convert from RGB24 to YUV420  
unsigned int uu0[352*288], vv0[352*288]; 
int ConvertRGB2YUV(int w,int h,unsigned char *bmp,unsigned char *yuv) 
{ unsigned int *uu,*vv; 
  unsigned int *pu1,*pu2,*pu3,*pu4;
  unsigned int *pv1,*pv2,*pv3,*pv4;
  unsigned char *r,*g,*b,*y,*u,*v; int i,j; uu=uu0; vv=vv0;
  if(uu==NULL || vv==NULL) 
  return 0; 
  y=yuv; 
  r=bmp; g=bmp+1; b=bmp+2; 
  for(i=0;i
  { 
    for(j=0;j
      { *y++=( RGB2YUV_YR[*r] +RGB2YUV_YG[*g]+RGB2YUV_YB[*b]+1048576)>>16; 
        *uu++=(-RGB2YUV_UR[*r] -RGB2YUV_UG[*g]+RGB2YUV_UBVR[*b]+8388608)>>16; 
        *vv++=( RGB2YUV_UBVR[*r]-RGB2YUV_VG[*g]-RGB2YUV_VB[*b]+8388608)>>16;
        r+=3; g+=3; b+=3; 
       } 
   }
   u=yuv+w*h; v=u+(w*h)/4; 
   pu1=uu0; pu2=pu1+1; pu3=pu1+w; pu4=pu3+1; 
   pv1=vv0; pv2=pv1+1; pv3=pv1+w; pv4=pv3+1; 
   for(i=0;i
   { 
     for(j=0;j
      { 
        *u++=(*pu1+*pu2+*pu3+*pu4)>>2; 
        *v++=(*pv1+*pv2+*pv3+*pv4)>>2;
        pu1+=2; pu2+=2; pu3+=2; pu4+=2; 
        pv1+=2; pv2+=2; pv3+=2; pv4+=2; 
       } 
      pu1+=w; pu2+=w; pu3+=w; pu4+=w;
      pv1+=w; pv2+=w; pv3+=w; pv4+=w; 
   } 
   return 1;
)

四、查看YUV420图片数据

    查看是否RGB转YUV420数据成功,可以将YUV420数据以二进制的方式保存为文本文件形式,通过YUVVIEWER软件读取文本文件进行查看。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值