YUV422与RGB互相转换(经验证在IPNC与PC上都可以)
来源:互联网 发布:我爱mac网站靠谱吗 编辑:程序博客网 时间:2024/06/03 16:00
前一段时间在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(代码下载)
#ifndef _RGB2YUV__#define _RGB2YUV__#include <iostream>using namespace std;#define TUNE(r) ( r < 0 ? 0 : (r > 255 ? 255 : r) )static int RGB_Y[256];static int RGBR_V[256];static int RGBG_U[256];static int RGBG_V[256];static int RGBB_U[256];static int YUVY_R[256];static int YUVY_G[256];static int YUVY_B[256];static int YUVU_R[256];static int YUVU_G[256];static int YUVU_B[256];static int YUVV_R[256];static int YUVV_G[256];static int YUVV_B[256];static int coff_rv[256];static int coff_gu[256];static int coff_gv[256];static int coff_bu[256];//直接采用公式浮点计算方式//仅RGB2YUV采用了查表法,所以有一部分表是没有用到的void InitTable(){int i;for(i = 0;i<256;i++){//初始化表,放大256倍RGB_Y[i] = 298 * (i - 16);RGBR_V[i] = 408 * (i - 128);RGBG_U[i] = 100 * (128- i);RGBG_V[i]= 208*(128-i);RGBB_U[i] =517 * (i - 128);//y=0.257*r+0.504*g+0.098*b+16//u = -0.148*r - 0.291*g + 0.439*b + 128//0.439*r - 0.368*g - 0.071*b + 128YUVY_R[i]=66*i;YUVY_G[i]=129*i;YUVY_B[i]=25*i;YUVU_R[i]=-38*i;YUVU_G[i]=-74*i;YUVU_B[i]=112*i;YUVV_R[i]=112*i;YUVV_G[i]=-94*i;YUVV_B[i]=-18*i;/*所用公式(此公式不适用)*pRGB = (unsigned char)(1.0*y + 8 + 1.402*(v-128)); pRGB++; // r*pRGB = (unsigned char)(1.0*y - 0.34413*(u-128) - 0.71414*(v-128)); pRGB++; // g*pRGB = (unsigned char)(1.0*y + 1.772*(u-128) + 0); pRGB++ ; */coff_rv[i] = (8+1.402*(i-128))*256;coff_gu[i] = -0.34413*(i-128)*256;coff_gv[i] = -0.71414*(i-128)*256;coff_bu[i] = 1.772*(i-128)*256;/*应该使用如下公式:Y’ = 0.257*R' + 0.504*G' + 0.098*B' + 16Cb' = -0.148*R' - 0.291*G' + 0.439*B' + 128Cr' = 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)*/}}void YUV2RGB422(unsigned char *pRGB, unsigned char *pYUV,int size){unsigned char y, u, v,y1;int r,g,b;unsigned int i=0;unsigned int loop = size>>1;while(loop-- >0){y = *pYUV; pYUV++;u = *pYUV; pYUV++;y1 = *pYUV;pYUV++;v = *pYUV; pYUV++;r = 1.164*(y-16) + 1.596*(v-128);g = 1.164*(y-16) - 0.813*(v-128) - 0.392*(u-128);b = 1.164*(y-16) + 2.017*(u-128);*pRGB = TUNE(r);pRGB++;*pRGB = TUNE(g);pRGB++;*pRGB = TUNE(b);pRGB++;r = 1.164*(y1-16) + 1.596*(v-128);g = 1.164*(y1-16) - 0.813*(v-128) - 0.392*(u-128);b = 1.164*(y1-16) + 2.017*(u-128);*pRGB = TUNE(r);pRGB++;*pRGB = TUNE(g);pRGB++;*pRGB = TUNE(b);pRGB++;}}//size 为图片的大小void RGB2YUV422(unsigned char *pRGB, unsigned char *pYUV,int size){unsigned char r,g,b,u,v,u1,v1,r1,g1,b1;//unsigned char *YUVBuff;//unsigned char* p;//p = YUVBuff;//int loop = size/2;int i;for( i=0;i<loop;i++){r = *pRGB; pRGB++;g = *pRGB; pRGB++;b = *pRGB; pRGB++;r1 = *pRGB; pRGB++;g1 = *pRGB; pRGB++;b1 = *pRGB; pRGB++;//new method --- rightint y = ((YUVY_R[r] + YUVY_G[g] + YUVY_B[b] + 128) >> 8) +16; u = ((YUVU_R[r] + YUVU_G[g] + YUVU_B[b] + 128) >> 8) + 128;v = ((YUVV_R[r] + YUVV_G[g] + YUVV_B[b] + 128) >> 8) + 128;int y1 = ((YUVY_R[r1] + YUVY_G[g1] + YUVY_B[b1] + 128) >> 8)+16;u1 = ((YUVU_R[r1] + YUVU_G[g1] + YUVU_B[b1] + 128) >> 8) + 128;v1 = ((YUVV_R[r1] + YUVV_G[g1] + YUVV_B[b1] + 128) >> 8) + 128;*pYUV++ = TUNE(y);*pYUV++ =(TUNE(u)+TUNE(u1))>>1;*pYUV++ = TUNE(y1);*pYUV++ = TUNE(v);}}void inline Yuv2RgbPixel(unsigned char y,unsigned char u,unsigned char v,unsigned char* rgbPixel){int r = (RGB_Y[y] + RGBR_V[v] + 128) >> 8;int g = ((RGB_Y[y] + RGBG_V[v]+RGBG_U[u]+ 128)>>8 );int b = ((RGB_Y[y] + RGBB_U[u]+128 )>>8);*rgbPixel=TUNE(r);rgbPixel++;*rgbPixel=TUNE(g);rgbPixel++;*rgbPixel=TUNE(b);}void YUV2RGB(unsigned char *pRGB, unsigned char *pYUV,int size)//444{unsigned char y, u, v;for(int i=0;i<size;i++){y = *pYUV; pYUV++;u = *pYUV; pYUV++;v = *pYUV; pYUV++;Yuv2RgbPixel(y,u,v,pRGB);pRGB += 3;}}void inline Rgb2YuvPiexl(unsigned char r,unsigned char g,unsigned char b,unsigned char* pYUV){int y = ((YUVY_R[r] + YUVY_G[g] + YUVY_B[b] + 128) >> 8) + 16; int u = ((YUVU_R[r] + YUVU_G[g] + YUVU_B[b] + 128) >> 8) + 128;int v = ((YUVV_R[r] + YUVV_G[g] + YUVV_B[b] + 128) >> 8) + 128;*pYUV = TUNEY(y);pYUV++;//*pYUV = u < 0 ? 0 : (u > 255 ? 255 : u);pYUV++; *pYUV =TUNE(u);pYUV++;*pYUV = TUNE(v);}void RGB2YUV(unsigned char *pRGB, unsigned char *pYUV,int size){unsigned char r,g,b,y,u,v;for(int i=0;i<size;i++){r = *pRGB; pRGB++;g = *pRGB; pRGB++;b = *pRGB; pRGB++;Rgb2YuvPiexl(r,g,b,pYUV);pYUV +=3;}}#endif
0 0
- YUV422与RGB互相转换(经验证在IPNC与PC上都可以)
- YUV422与RGB互相转换
- YUV422与RGB互相转换
- YUV422与RGB互相转
- HSV与RGB互相转换
- RGB与Ycbcr空间的互相转换
- RGB和HSV区别与互相转换
- RGB与16进制值互相转换
- RGB与Lab颜色空间互相转换
- YUV422 to RGB 转换
- RGB与YCbCr颜色空间的互相转换公式
- RGB与YCbCr颜色空间的互相转换公式
- 主机与虚拟机都可以上网,但是互相ping不通
- 论YUV422(YUYV)与YUV420相互转换
- 色相(H)饱和度(S)明度(L)与RGB的转换以及在android上的试验
- 【LIS 问题与 LCS 问题可以互相转换】
- RGB与YUV转换
- RGB与HSV转换
- 题目1023:EXCEL排序
- 存储方式SharePreferences
- 微软面试100题之第4题
- java + selenium测试框架(之等待机制) 版本演化二
- 用PHP实现进度条效果原理,似服务器推
- YUV422与RGB互相转换(经验证在IPNC与PC上都可以)
- Android Studio使用说明
- #raspberry#基于树梅派的REST Web API构架
- php 图片水印(图片合并原理)
- 《UNIX环境高级编程》第二版源码在Ubuntu下的编译
- NYOJ 1012 RMQ with shift
- socket通信 方法解惑
- CreateFileA与COM
- C语言实现写入日志文件