图像算法研究---一种简单的YUV转RGB的优化算法
来源:互联网 发布:linux dhcp安装 编辑:程序博客网 时间:2024/06/05 19:37
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;
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;};效果图:
原图
使用浮点型RGB-YUV-RGB结果图
使用优化版RGB-YUV-RGB结果图
在说一下,这个优化纯粹是追求速度,当然,效果差异很小,如果你需要的是100%的准确,最好还是要使用浮点计算。有什么问题,联系我,QQ1358009172
- 图像算法研究---一种简单的YUV转RGB的优化算法
- 图像算法研究---一种简单的YUV转RGB的优化算法(2)
- 图像算法研究——一种简单的YUV转RGB的优化算法(2)
- 求YUV转RGB的算法
- 算法优化:rgb向yuv的转化最优算法,快得让你吃惊(转)
- [转]算法优化:rgb向yuv的转化最优算法,快得让你吃惊!
- rgb向yuv转化的最优算法
- YUV与RGB图像的互转
- YUV图像实时去雾算法的优化与改进
- 算法优化:rgb向yuv的转化最优算法,快得让你吃惊!
- 算法优化:rgb向yuv的转化最优算法,快得让你吃惊!
- 算法优化:rgb向yuv的转化最优算法,快得让你吃惊!
- 算法优化:rgb向yuv的转化最优算法,快得让你吃惊!
- 算法优化:rgb向yuv的转化最优算法,快得让你吃惊!
- 算法优化:rgb向yuv的转化最优算法,快得让你吃惊!
- 算法优化:rgb向yuv的转化最优算法,快得让你吃惊!
- 算法优化:rgb向yuv的转化最优算法,ALPHABLEND算法优化快得让你吃惊!
- YUV 转 RGB快速算法
- 《Java多线程之CAS》
- zookeeper知识点一(同步创建节点)
- 最小生成树算法和单源最短路径算法
- Unity3D Shader官方教程翻译(四)----Shader语法:SubShader
- SQL Server数据库ROW_NUMBER()函数使用详解
- 图像算法研究---一种简单的YUV转RGB的优化算法
- 类加载及对象创建
- 禁止拖动滚动条的mp4播放器
- 83. Remove Duplicates from Sorted List
- 使用 harbor 搭建 docker 私有镜像仓库
- Android如何设置图标字体 IconFont(HTML图标)
- C++使用ODBC连接数据库时出现无法将SQLCHAR*转换为SQLWCHAR*
- PyGobject(三十二)布局容器之Window
- Android Studio 使用技巧汇总