YUV与RGB的相互转换一直以来都是非常常用的基础算法,如何才能最高效的转换,成为一个难点问题,尤其是目前视频直播火热的时候,这些算法的优化也越发重要。

今天我结合自己的一些经验,给大家介绍一个简单的优化算法。

首先,我们看下最常用的YUV与RGB相互转换的算法公式,如下所示:

注意,RGB取值范围均为0-255:

1,RGB转YUV

Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B

2,YUV转RGB

R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U

我的优化方案如下:

优化1:看到上述算法,从算法优化角度来看,算法计算中,最好不要出现浮点运算,浮点运算比较耗时;

基于这一点,我们做如下操作:

Y * 256 = 0.299 * 256R + 0.587 * 256G + 0.114 * 256B

U * 256 = -0.147 * 256R - 0.289 * 256G + 0.436 * 256B
V * 256 = 0.615 * 256R - 0.515 * 256G - 0.100 * 256B

R * 256 = Y * 256 + 1.14 * 256V
G * 256 = Y * 256 - 0.39 * 256U - 0.58 * 256V
B * 256 = Y * 256 + 2.03 * 256U

简化上面的公式如下:

256Y = 76.544R + 150.272G + 29.184B

256U = -37.632R - 73.984G + 111.616B

256V = 157.44R - 131.84G - 25.6B

256R = 256Y + 291.84V

256G = 256Y - 99.84U - 148.48V

256B = 256Y + 519.68U

做到这一步,我这里要说明一下:我们这里的转换是有损的,适用于追求速度,而对效果要求不是100%准确的情况。

然后,我们就可以对上述公式进一步优化,彻底干掉小数:

256Y = 77R + 150G + 29B

256U = -38R - 74G + 112B

256V = 158R - 132G - 26B

256R = 256Y + 292V

256G = 256Y - 100U - 149V

256B = 256Y + 520U

实际上就是四舍五入,为什么要乘以256,这是实际上是为了缩小误差,当然你这个地方乘数越大,误差越小。

优化2:干掉所有乘法,用移位运算表示;

上述公式,我们可以用移位进行简单优化:

Y = (77R + 150G + 29B) >> 8

U = (-38R - 74G + 112B) >> 8

V = (158R - 132G - 26B) >> 8

R = (256Y + 292V) >> 8

G = (256Y - 100U - 149V) >> 8

B = (256Y + 520U) >> 8

做到此处,已经没有了浮点运算量了,但是我们发现虽然采用了移位运算,但是,公式中还有很多乘法运算,乘法跟移位运算相比,还是效率太低了,因此,我们将把所有乘法都改成移位运算。

如何将常数乘法改成移位运算?
这里给个例子:

Y=Y*9可以改为:Y=(Y<<3)+Y

因此,我们可以讲YUV的公式继续改为最简:

RGB转YUV:

Y = ((R << 6) + (R << 3) + (R << 2) + R + (G << 7) + (G << 4) + (G << 2) + (G << 1) + (B << 4) + (B << 3) + (B << 2) + B) >> 8;
 U = (-((R << 5) + (R << 2) + (R << 1)) - ((G << 6) + (G << 3) + (G << 1)) + ((B << 6) + (B << 5) + (B << 4))) >> 8;
 V = ((R << 7) + (R << 4) + (R << 3) + (R << 2) + (R << 1) - ((G << 7) + (G << 2)) - ((B << 4) + (B << 3) + (B << 1))) >> 8;

YUV转RGB:

R   = ((Y << 8) + ((V << 8) + (V << 5) + (V << 2))) >> 8;
 G = ((Y << 8) - ((U << 6) + (U << 5) + (U << 2)) - ((V << 7) + (V << 4) + (V << 2) + V)) >> 8;  
 B = ((Y << 8) + (U << 9) + (U << 3)) >> 8;

至此,YUV与RGB的相互转换公式就优化完毕了,这个优化,在移动端,速度会有很大的提高,至于一些测试数据,我就不列举了,只给个效果图吧,大家可以直接试一下就知道了,最后,给出C的代码如下:

static void RGBToYUV(int Red, int Green, int Blue, int* Y,int* U,int* V)
{*Y = ((Red << 6) + (Red << 3) + (Red << 2) + Red + (Green << 7) + (Green << 4) + (Green << 2) + (Green << 1) + (Blue << 4) + (Blue << 3) + (Blue << 2) + Blue) >> 8;*U = (-((Red << 5) + (Red << 2) + (Red << 1)) - ((Green << 6) + (Green << 3) + (Green << 1)) + ((Blue << 6) + (Blue << 5) + (Blue << 4))) >> 8;*V = ((Red << 7) + (Red << 4) + (Red << 3) + (Red << 2) + (Red << 1) - ((Green << 7) + (Green << 2)) - ((Blue << 4) + (Blue << 3) + (Blue << 1))) >> 8;
};
static void YUVToRGB(int Y, int U, int V, int* Red, int* Green, int* Blue)
{*Red   = ((Y << 8) + ((V << 8) + (V << 5) + (V << 2))) >> 8;*Green = ((Y << 8) - ((U << 6) + (U << 5) + (U << 2)) - ((V << 7) + (V << 4) + (V << 2) + V)) >> 8;  *Blue = ((Y << 8) + (U << 9) + (U << 3)) >> 8;
};

图像算法研究---一种简单的YUV转RGB的优化算法相关推荐

  1. 一种改进非线性收敛方式的灰狼优化算法研究

    文章目录 一.理论基础 1.基本灰狼优化算法(GWO) 2.改进灰狼优化算法(CGWO) (1)引入混沌策略反向学习初始化种群 (2)改进非线性收敛因子 (3)Cauchy变异算子 二.算法实现步骤 ...

  2. 多目标人工秃鹫优化算法(MATLAB源码分享,智能优化算法) 提出了一种多目标版本的人工秃鹫优化算法(AVOA)

    多目标人工秃鹫优化算法(MATLAB源码分享,智能优化算法) 提出了一种多目标版本的人工秃鹫优化算法(AVOA),用于多目标优化问题. AVOA的灵感来源于非洲秃鹫的生活方式. 档案.网格和领导者选择 ...

  3. 鱼眼校正c语言算法,一种简单而精确的鱼眼图像校正算法研究

    舒旭 摘 要: 针对鱼眼图像的校正提出了一种有效区域提取算法,并在鱼眼图像的球面物投影平面展开时与目标半立方体的校正平面建立线性映射.实验结果表明,该算法能有效地提取鱼眼图像轮廓的有效区域,同时半立方 ...

  4. 优化算法|MOAVOA:一种新的多目标人工秃鹰优化算法(Matlab代码实现)

  5. 教学优化算法的简单介绍

    目录 摘要 背景 算法 学生初始化 教学阶段 学习阶段 流程总结 优缺点 优点 缺点 一些改进 总结 参考文献 摘要 教学优化算法(Teaching-learning-based optimizati ...

  6. 蝙蝠算法c语言,一种新颖的群智能算法:飞蛾扑火优化算法

    李志明+莫愿斌+张森 摘要 飞蛾扑火优化(MFO)算法是一种新颖的群智能优化算法,该算法的主要灵感来源于飞蛾在自然界中被称为横向定位的飞行方式.作为一种新提出的仿生群智能优化算法,分析了飞蛾扑火优化算 ...

  7. skew算法_一种新型Skew Tent映射的混沌混合优化算法

    一种新型 Skew Tent 映射的混沌混合优化算法 江善和 ; 王其申 ; 江巨浪 [期刊名称] <控制理论与应用> [年 ( 卷 ), 期] 2007(024)002 [摘要] 针对已 ...

  8. 最简单的基于FFmpeg的libswscale的示例(YUV转RGB)

    ===================================================== 最简单的基于FFmpeg的libswscale的示例系列文章列表: 最简单的基于FFmpeg ...

  9. 最简单的视音频播放示例3 Direct3D播放YUV,RGB(通过Surface)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! ==== ...

最新文章

  1. JavaScript如何诞生
  2. 箭头函数中的this的使用
  3. spring 监听器 IntrospectorCleanupListener简介
  4. Keras学习笔记:序列式模型
  5. SQLSERVER 2014 SP1 的服务器 日志文件无法收缩的处理
  6. 使用Qt D-Bus适配器
  7. QT的QNoDraw类的使用
  8. linux父子进程字写父读无效,linux父子进程
  9. php pdo mysql query_PHP+MYSQL中使用PDO的query方法
  10. 用Log4Net来记录系统的日志信息
  11. 火山引擎 veStack 在企业办公场景的落地实践
  12. Android4.1MediaPlayer无缝播放
  13. http 协议入门
  14. 端口打流互通功能测试
  15. 网络协议介绍(NetBIOS,NETBEUI,IPX/SPX,TCP/IP)
  16. 毕设项目 - 基于SSM的教师工作考核绩效管理系统(含源码+论文)
  17. 腾讯与清华大学物理系签署合作备忘录,探索材料计算新领域
  18. win10前面板耳机无声音解决
  19. c语言中ch1和ch2是什么意思,2020-05-26(C语言)1.将串str中所有值为ch1的字符转换成ch2的字符,如果str为空串,或者串中不含值为ch1的字符,则什么都不做.2.逆转函数...
  20. 全球各国主要电商平台

热门文章

  1. zookeeper安装启动报错引发的版本取用思考
  2. CoreGraphics之CGContextSaveGState与UIGraphicsPushContext
  3. 如何更有价值采集数据、高效分析数据?
  4. ubuntu修改主机名
  5. FNV哈希算法【转】
  6. Python中操控ssh和sftp
  7. RHCE 学习笔记(16) - KickStart
  8. 数据库的增删改查和使用流程
  9. python代码制作configure文件
  10. oracle 误删表空间文件启动不了数据库的解决办法