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