zoukankan      html  css  js  c++  java
  • YUV422与RGB互相转换

     

    YUV422与RGB互相转换(经验证在IPNC与PC上都可以)

    前一段时间在DM8168中进行颜色空间的转换,在网上找了些程序,自己也根据网上的改了下,由于能力问题,实在是不好意思说做了好几天才弄出来, 主要是因为YUV<—>RGB有各种各样的转换公式。在多次的实验修改后,终于找到了对的公式,共享出来,以便需要的人选择。

    在监控系统中大多采用YUV的颜色空间,原因不说了,网上搜YUV转RGB各种介绍。

    在TI的视频英语达芬奇系列中(这里只测试了DVR、IPNC),

    采用如下公式:

    yCbCr<-->rgb
     
    Y’ = 0.257*R' + 0.504*G' + 0.098*B' + 16
     Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
     Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128


    R' = 1.164*(Y’-16) + 1.596*(Cr'-128)
     G' = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)
     B' = 1.164*(Y’-16) + 2.017*(Cb'-128)

    转换效果图如下

    第一幅是原图YUV,第二幅是转为RGB后存为bmp,反转是因为BMP图像是从最下面一行开始存取的原因,最下面一副是转回YUV的图像。

    代码如下,代码中YUV采用YUYVYUYV的格式,RGB为RGBRGBRGB.....

    http://download.csdn.net/detail/guo8113/7318031(代码下载)

      1 #ifndef _RGB2YUV__ 
      2 #define _RGB2YUV__ 
      3 #include <iostream> 
      4 using namespace std; 
      5  
      6 #define TUNE(r) ( r < 0 ? 0 : (r > 255 ? 255 : r) ) 
      7  
      8 static  int RGB_Y[256]; 
      9 static  int RGBR_V[256]; 
     10 static  int RGBG_U[256]; 
     11 static  int RGBG_V[256]; 
     12 static  int RGBB_U[256]; 
     13  
     14  
     15 static  int YUVY_R[256]; 
     16 static  int YUVY_G[256]; 
     17 static  int YUVY_B[256]; 
     18  
     19 static  int YUVU_R[256]; 
     20 static  int YUVU_G[256]; 
     21 static  int YUVU_B[256]; 
     22  
     23 static  int YUVV_R[256]; 
     24 static  int YUVV_G[256]; 
     25 static  int YUVV_B[256]; 
     26  
     27 static int coff_rv[256]; 
     28 static int coff_gu[256]; 
     29 static int coff_gv[256]; 
     30 static int coff_bu[256]; 
     31  
     32 //直接采用公式浮点计算方式 
     33 //仅RGB2YUV采用了查表法,所以有一部分表是没有用到的 
     34 void InitTable() 
     35 { 
     36     int i; 
     37     for(i = 0;i<256;i++) 
     38     { 
     39         //初始化表,放大256倍 
     40         RGB_Y[i] = 298 * (i - 16); 
     41         RGBR_V[i] = 408 * (i - 128); 
     42         RGBG_U[i] = 100 * (128- i); 
     43         RGBG_V[i]= 208*(128-i); 
     44         RGBB_U[i] =517 * (i - 128); 
     45         //y=0.257*r+0.504*g+0.098*b+16 
     46         //u = -0.148*r - 0.291*g + 0.439*b + 128 
     47         //0.439*r - 0.368*g - 0.071*b + 128 
     48         YUVY_R[i]=66*i; 
     49         YUVY_G[i]=129*i; 
     50         YUVY_B[i]=25*i; 
     51         YUVU_R[i]=-38*i; 
     52         YUVU_G[i]=-74*i; 
     53         YUVU_B[i]=112*i; 
     54         YUVV_R[i]=112*i; 
     55         YUVV_G[i]=-94*i; 
     56         YUVV_B[i]=-18*i; 
     57        /*所用公式(此公式不适用)
     58         *pRGB = (unsigned char)(1.0*y + 8 + 1.402*(v-128));    pRGB++;                 // r
     59         *pRGB = (unsigned char)(1.0*y - 0.34413*(u-128) - 0.71414*(v-128));  pRGB++;   // g
     60         *pRGB = (unsigned char)(1.0*y + 1.772*(u-128) + 0);    pRGB++ ;  
     61         */ 
     62         coff_rv[i] = (8+1.402*(i-128))*256; 
     63         coff_gu[i] = -0.34413*(i-128)*256; 
     64         coff_gv[i] = -0.71414*(i-128)*256; 
     65         coff_bu[i] = 1.772*(i-128)*256; 
     66  
     67         /*应该使用如下公式:
     68 Y’ = 0.257*R' + 0.504*G' + 0.098*B' + 16
     69 Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128
     70 Cr' = 0.439*R' - 0.368*G' - 0.071*B' + 128(标红的两组公式是可逆的转换)
     71 R' = 1.164*(Y’-16) + 1.596*(Cr'-128)
     72 G' = 1.164*(Y’-16) - 0.813*(Cr'-128) - 0.392*(Cb'-128)
     73 B' = 1.164*(Y’-16) + 2.017*(Cb'-128)
     74 */ 
     75     } 
     76 } 
     77  
     78 void YUV2RGB422(unsigned char *pRGB, unsigned char *pYUV,int size) 
     79 { 
     80     unsigned char y, u, v,y1; 
     81     int r,g,b; 
     82     unsigned int i=0; 
     83     unsigned int loop = size>>1; 
     84     while(loop-- >0) 
     85     { 
     86          
     87         y = *pYUV; pYUV++; 
     88         u = *pYUV; pYUV++; 
     89         y1 = *pYUV;pYUV++; 
     90         v = *pYUV; pYUV++; 
     91      
     92         r = 1.164*(y-16) + 1.596*(v-128); 
     93         g = 1.164*(y-16) - 0.813*(v-128) - 0.392*(u-128); 
     94         b = 1.164*(y-16) + 2.017*(u-128); 
     95  
     96         *pRGB = TUNE(r);pRGB++; 
     97         *pRGB = TUNE(g);pRGB++; 
     98         *pRGB = TUNE(b);pRGB++; 
     99  
    100          r = 1.164*(y1-16) + 1.596*(v-128); 
    101          g = 1.164*(y1-16) - 0.813*(v-128) - 0.392*(u-128); 
    102          b = 1.164*(y1-16) + 2.017*(u-128); 
    103          *pRGB = TUNE(r);pRGB++; 
    104          *pRGB = TUNE(g);pRGB++; 
    105          *pRGB = TUNE(b);pRGB++; 
    106      } 
    107   
    108  }
    109  
    110  //size 为图片的大小 
    111  void RGB2YUV422(unsigned char *pRGB, unsigned char *pYUV,int size) 
    112  { 
    113      unsigned char r,g,b,u,v,u1,v1,r1,g1,b1; 
    114      //unsigned char *YUVBuff; 
    115      //unsigned char* p; 
    116      //p = YUVBuff;// 
    117      int loop = size/2; 
    118      int i; 
    119      for( i=0;i<loop;i++) 
    120      { 
    121          r = *pRGB; pRGB++; 
    122          g = *pRGB; pRGB++; 
    123          b = *pRGB; pRGB++; 
    124          r1 = *pRGB; pRGB++; 
    125          g1 = *pRGB; pRGB++; 
    126          b1 = *pRGB; pRGB++; 
    127           
    128          //new method ---  right 
    129          int y = ((YUVY_R[r] + YUVY_G[g] + YUVY_B[b] + 128) >> 8) +16;      
    130          u = ((YUVU_R[r] + YUVU_G[g] + YUVU_B[b] + 128) >> 8) + 128; 
    131          v = ((YUVV_R[r] + YUVV_G[g] + YUVV_B[b] + 128) >> 8) + 128; 
    132          int y1 = ((YUVY_R[r1] + YUVY_G[g1] + YUVY_B[b1] + 128) >> 8)+16; 
    133          u1 = ((YUVU_R[r1] + YUVU_G[g1] + YUVU_B[b1] + 128) >> 8) + 128; 
    134          v1 = ((YUVV_R[r1] + YUVV_G[g1] + YUVV_B[b1] + 128) >> 8) + 128; 
    135           
    136          *pYUV++ = TUNE(y); 
    137          *pYUV++ =(TUNE(u)+TUNE(u1))>>1; 
    138          *pYUV++ = TUNE(y1); 
    139          *pYUV++ = TUNE(v); 
    140      }    
    141       
    142  } 
    143   
    144  void inline Yuv2RgbPixel(unsigned char y,unsigned char u,unsigned char v, unsigned char* rgbPixel) 
    145  { 
    146      int r = (RGB_Y[y] + RGBR_V[v] + 128) >> 8; 
    147      int g = ((RGB_Y[y] + RGBG_V[v]  +RGBG_U[u]+ 128)>>8 ); 
    148      int b = ((RGB_Y[y] + RGBB_U[u]+128 )>>8);  
    149      *rgbPixel=TUNE(r);rgbPixel++; 
    150      *rgbPixel=TUNE(g);rgbPixel++; 
    151      *rgbPixel=TUNE(b); 
    152  }
    153  
    154  void YUV2RGB(unsigned char *pRGB, unsigned char *pYUV,int size)//444 
    155  { 
    156      unsigned char y, u, v; 
    157   
    158      for(int i=0;i<size;i++) 
    159      { 
    160          y = *pYUV; pYUV++; 
    161          u = *pYUV; pYUV++; 
    162          v = *pYUV; pYUV++; 
    163   
    164          Yuv2RgbPixel(y,u,v,pRGB); 
    165          pRGB += 3; 
    166      } 
    167       
    168  } 
    169  
    170  void inline Rgb2YuvPiexl(unsigned char r,unsigned char g,unsigned char b,unsigned char* pYUV) 
    171  { 
    172      int y = ((YUVY_R[r] + YUVY_G[g] + YUVY_B[b] + 128) >> 8) + 16;      
    173      int u = ((YUVU_R[r] + YUVU_G[g] + YUVU_B[b] + 128) >> 8) + 128; 
    174      int v = ((YUVV_R[r] + YUVV_G[g] + YUVV_B[b] + 128) >> 8) + 128; 
    175      *pYUV = TUNEY(y);pYUV++; 
    176          //*pYUV = u < 0 ? 0 : (u > 255 ? 255 : u);pYUV++;  
    177      *pYUV =TUNE(u);pYUV++; 
    178      *pYUV = TUNE(v); 
    179  } 
    180  
    181  void RGB2YUV(unsigned char *pRGB, unsigned char *pYUV,int size) 
    182  { 
    183      unsigned char r,g,b,y,u,v; 
    184      for(int i=0;i<size;i++) 
    185      { 
    186          r = *pRGB; pRGB++; 
    187          g = *pRGB; pRGB++; 
    188          b = *pRGB; pRGB++; 
    189          Rgb2YuvPiexl(r,g,b,pYUV); 
    190          pYUV +=3; 
    191   
    192      }    
    193  } 
    194  #endif 

    http://www.61ic.com/Article/DaVinci/TMS320DM81x/201408/52651.html

    http://blog.csdn.net/xgmiao/article/details/23512021

    http://www.cnblogs.com/jck34/p/3898569.html

    http://blog.csdn.net/onion2007/article/details/46805335

  • 相关阅读:
    C++ 整型长度的获取 不同的系统
    第二章习题 C++
    输入cin对象的用法
    将Mnist手写数字库转化为图片形式 和标签形式
    寻找图片中数字的轮廓并裁剪 扣取数字
    Linux中的日志功能
    Linux中的系统默认日志
    Linux中进程在前后台的切换
    Linux中的服务管理
    Linux中的流程控制语句
  • 原文地址:https://www.cnblogs.com/eustoma/p/6666444.html
Copyright © 2011-2022 走看看