YUV422与RGB互相转

2023-11-06 06:40
文章标签 互相 rgb yuv422

本文主要是介绍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(代码下载)

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  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. //size 为图片的大小  
  110. void RGB2YUV422(unsigned char *pRGB, unsigned char *pYUV,int size)  
  111. {  
  112.     unsigned char r,g,b,u,v,u1,v1,r1,g1,b1;  
  113.     //unsigned char *YUVBuff;  
  114.     //unsigned char* p;  
  115.     //p = YUVBuff;//  
  116.     int loop = size/2;  
  117.     int i;  
  118.     for( i=0;i<loop;i++)  
  119.     {  
  120.         r = *pRGB; pRGB++;  
  121.         g = *pRGB; pRGB++;  
  122.         b = *pRGB; pRGB++;  
  123.         r1 = *pRGB; pRGB++;  
  124.         g1 = *pRGB; pRGB++;  
  125.         b1 = *pRGB; pRGB++;  
  126.           
  127.         //new method ---  right  
  128.         int y = ((YUVY_R[r] + YUVY_G[g] + YUVY_B[b] + 128) >> 8) +16;       
  129.         u = ((YUVU_R[r] + YUVU_G[g] + YUVU_B[b] + 128) >> 8) + 128;  
  130.         v = ((YUVV_R[r] + YUVV_G[g] + YUVV_B[b] + 128) >> 8) + 128;  
  131.         int y1 = ((YUVY_R[r1] + YUVY_G[g1] + YUVY_B[b1] + 128) >> 8)+16;  
  132.         u1 = ((YUVU_R[r1] + YUVU_G[g1] + YUVU_B[b1] + 128) >> 8) + 128;  
  133.         v1 = ((YUVV_R[r1] + YUVV_G[g1] + YUVV_B[b1] + 128) >> 8) + 128;  
  134.           
  135.         *pYUV++ = TUNE(y);  
  136.         *pYUV++ =(TUNE(u)+TUNE(u1))>>1;  
  137.         *pYUV++ = TUNE(y1);  
  138.         *pYUV++ = TUNE(v);  
  139.     }     
  140.       
  141. }  
  142.   
  143. void inline Yuv2RgbPixel(unsigned char y,unsigned char u,unsigned char v,  
  144.     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. void YUV2RGB(unsigned char *pRGB, unsigned char *pYUV,int size)//444  
  154. {  
  155.     unsigned char y, u, v;  
  156.   
  157.     for(int i=0;i<size;i++)  
  158.     {  
  159.         y = *pYUV; pYUV++;  
  160.         u = *pYUV; pYUV++;  
  161.         v = *pYUV; pYUV++;  
  162.   
  163.         Yuv2RgbPixel(y,u,v,pRGB);  
  164.         pRGB += 3;  
  165.     }  
  166.       
  167. }  
  168. void inline Rgb2YuvPiexl(unsigned char r,unsigned char g,unsigned char b,unsigned char* pYUV)  
  169. {  
  170.     int y = ((YUVY_R[r] + YUVY_G[g] + YUVY_B[b] + 128) >> 8) + 16;       
  171.     int u = ((YUVU_R[r] + YUVU_G[g] + YUVU_B[b] + 128) >> 8) + 128;  
  172.     int v = ((YUVV_R[r] + YUVV_G[g] + YUVV_B[b] + 128) >> 8) + 128;  
  173.     *pYUV = TUNEY(y);pYUV++;  
  174.         //*pYUV = u < 0 ? 0 : (u > 255 ? 255 : u);pYUV++;   
  175.     *pYUV =TUNE(u);pYUV++;  
  176.     *pYUV = TUNE(v);  
  177. }  
  178. void RGB2YUV(unsigned char *pRGB, unsigned char *pYUV,int size)  
  179. {  
  180.     unsigned char r,g,b,y,u,v;  
  181.     for(int i=0;i<size;i++)  
  182.     {  
  183.         r = *pRGB; pRGB++;  
  184.         g = *pRGB; pRGB++;  
  185.         b = *pRGB; pRGB++;  
  186.         Rgb2YuvPiexl(r,g,b,pYUV);  
  187.         pYUV +=3;  
  188.   
  189.     }     
  190. }  
  191. #endif  

这篇关于YUV422与RGB互相转的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/355040

相关文章

MFC中App,Doc,MainFrame,View各指针的互相获取

纸上得来终觉浅,为了熟悉获取方法,我建了个SDI。 首先说明这四个类的执行顺序是App->Doc->Main->View 另外添加CDialog类获得各个指针的方法。 多文档的获取有点小区别,有时间也总结一下。 //  App void CSDIApp::OnApp() {      //  App      //  Doc     CDocument *pD

Jasperreports+jaspersoft studio学习教程(七)- 子报表Subreport(父子报表互相传值)

转载:https://blog.csdn.net/shiyun123zw/article/details/79221708 有很多人都说Jasperreports不适合中国式复杂报表,实际上运用好父子报表可以解决大部分问题了。例如下面的表。每个学生的学科数目不固定,且每个学生后有相当于小计的平均分。有点复杂度的报表,可以使用子报表解决。 8.1 设计报表模板 8.1.1 新建主模板De

Excel查询颜色RGB值

1.选中单元格,点右键,设置单元格格式-填充-其他颜色-自定义,下面显示的就是该单元格颜色的RGB值 2.与十六进制换算: https://www.sioe.cn/yingyong/yanse-rgb-16/

HSV颜色空间和RGB颜色空间相互转换C语言实现

HSV(Hue, Saturation, Value)是根据颜色的直观特性由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。 色调H 用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色

RGB色转为灰度色算法-img2ascii_char

一、基础   对于彩色转灰度,有一个很著名的心理学公式: Gray = R0.299 + G0.587 + B0.114 二、整数算法   而实际应用时,希望避免低速的浮点运算,所以需要整数算法。   注意到系数都是3位精度的没有,我们可以将它们缩放1000倍来实现整数运算算法: Gray = (R299 + G587 + B114 + 500) / 1000   RGB一般是8位精度,现在缩放1

java 图像RGB,图像红、绿、蓝、灰 化

把图形进行红、绿、蓝、灰 化,并保存     /** * 名词解释: * 饱和度是指色彩的鲜艳程度,也称色彩的纯度。 * 灰度:使用黑色调表示物体,即用黑色为基准色,不同的饱和度的黑色来显示图像。 * 像素:如同摄影的相片一样,数码影像也具有连续性的浓淡阶调,我们若把影像放大数倍,会发现这些连续色调其实是由许多色彩相近的小方点所组成, * 这些小方点就是构成影像的最小单元——像素。是分

字符串和数字之间的互相转换

字符串和数字之间的互相转换 将字符串转换为数字 函数:atof() 头文件:stdlib.h 函数原型:double atof( const char *string ) 因为double可以转换为int ,所以该函数参数也可以是int char str[100];scanf("%s",str);int a=atof(str); printf("%d",a+1);

#FFFFFF 和RGB的相互转化

#00b3e9 --->RGB(0,179,233)的转化 float R = (float)((0x00b3e9 & 0xFF0000)>>16); --> 0 float G = (float)((0x00b3e9 & 0xFF00)>>8); --> 179 float B = (float)((0x00b3e9 & 0xFF)); --> 233

使用FFmpeg的AVFilter转换YUV到RGB

AVFilter 是 FFmpeg 库 libavfilter 的核心组件,提供了一套强大的音视频处理框架,用于对音视频流进行复杂的过滤、转换和效果处理。通过 AVFilter,开发者可以构建自定义的滤镜图(filter graph),实现各种音视频处理任务,如颜色空间转换、缩放、裁剪、特效添加等。 以下是对 AVFilter 的详细介绍,包括其架构、关键概念、使用方法以及示例代码。 1. A