博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SSE图像算法优化系列十四:局部均方差及局部平方差算法的优化。
阅读量:7081 次
发布时间:2019-06-28

本文共 1461 字,大约阅读时间需要 4 分钟。

  关于局部均方差有着较为广泛的应用,在我博客的及中都有谈及,即可以用于去噪也可以用来增强图像,但是直接计算其计算量较大,一般都是通过某种方式进行优化,典型的即通过积分图来处理:

          {\text{Var}}(X)={\frac  {1}{n}}\sum _{​{i=1}}^{n}(x_{i}-\mu )^{2}\quad {\text{and}}\quad \mu ={\frac  {1}{n}}\sum _{​{i=1}}^{n}x_{i}

       展开:

                     {\text{Var}}(x)={\frac  {1}{n}}\sum _{​{i=1}}^{n}\left(x_{i}^{2}-2x_{i}\mu +\mu ^{2}\right)

                                  ={\frac  {1}{n}}\sum _{​{i=1}}^{n}x_{i}^{2}-{\frac  {1}{n}}\sum _{​{i=1}}^{n}2x_{i}\mu +\mu ^{2}

                                  ={\frac  {1}{n}}\sum _{​{i=1}}^{n}x_{i}^{2}-{\frac  {1}{n}}\sum _{​{i=1}}^{n}2x_{i}\mu +{\frac  {1}{n^{2}}}\left(\sum _{​{i=1}}^{n}x_{i}\right)^{2}

                                 ={\frac  {1}{n}}\sum _{​{i=1}}^{n}x_{i}^{2}-{\frac  {2\mu }{n}}\sum _{​{i=1}}^{n}x_{i}+{\frac  {1}{n^{2}}}\left(\sum _{​{i=1}}^{n}x_{i}\right)^{2}

                                 ={\frac  {1}{n}}\sum _{​{i=1}}^{n}x_{i}^{2}-{\frac  {2}{n^{2}}}\left(\sum _{​{i=1}}^{n}x_{i}\right)^{2}+{\frac  {1}{n^{2}}}\left(\sum _{​{i=1}}^{n}x_{i}\right)^{2}

                                 ={\frac  {1}{n}}\sum _{​{i=1}}^{n}x_{i}^{2}-{\frac  {1}{n^{2}}}\left(\sum _{​{i=1}}^{n}x_{i}\right)^{2}

                                 ={\frac  {1}{n}}\sum _{​{i=1}}^{n}x_{i}^{2}-\left({\frac  {1}{n}}\sum _{​{i=1}}^{n}x_{i}\right)^{2}

                                ={\frac  {1}{n}}\left(\sum _{​{i=1}}^{n}x_{i}^{2}-{\frac  {1}{n}}\left(\sum _{​{i=1}}^{n}x_{i}\right)^{2}\right)

  上式中两个累积一个是平方积分图,一个是累加积分图,累加积分图在中曾经谈及,而平方积分图由于数据范围的问题,用int类型的数据来处理的话,只能处理很小很小的图,因此需要使用浮点类型,经过测试,如果使用SSE指令,由于SSE的浮点计算精度实在是低,比FPU的还要低,积分图这种累加性质的算法计算出来的结果会存在很大的误差,特别是在图像比较宽而半径比较小时,会看到明显的错误结果,半径稍微大点时,也会有明显竖条纹出现(小图像好像不会出现什么大问题),如下图所示:

                 

            小半径                          大半径                     合理的结果     

  因此,如果使用积分图,考虑各种类型的图像,最好是使用double类型保存中间的积分图数据,这是个很可观的内存消耗,也会导致时间的增加。

  在一文中,我们描述了Boxblur的优化,优化后的速度即比传统的快,也占用很少的内存,我们观察下BoxBlur的累加式: 以及像素平方的累加式,他们除理数据不一样外,其他并无本质的区别的,因此也是可以使用类似于Boxblur的方式进行优化和处理的,这样上述算法就变为了2个这种累积算法的同步进行算法,并且同步进行能够减少很多重复数据的加载和处理,比单独进行两个过程其实是要更节省时间的。

  那么需要注意的时,由于是对像素的平方进行累加,还考虑使用int类型来保存列累加值以及水平方向的累加值,那么理论上讲最大的安全半径可以达到90(不会产生溢出),计算如下:

    Sqrt(Int.MaxValue / (Byte.MaxValue * Byte.MaxValue)) / 2 - 1 = Sqrt(2147483647 / 65025) / 2 - 1 = 90

  对于局部均方差相关的算法来说,90的半径已经完全满足了实际的需求。

  使用SSE优化,实际测试表面,对于3000*2000的灰度图求取均方差大约需要13ms(包括了最后的求sqrt过程的时间,是相当快的)。

  另外,局部均方差是像素领域的值减去该领域的平均值的平方累积和,这样的结果在强边缘处均方差会特别强烈,用于某法会出现边缘效应,如果我们对这个稍微改造下,使用像素领域的值减去领域的模糊值,在求累加值,会不会有什么结果呢,此时假如平均值用y表示,则需要计算这个值,同样的y就是上述的Boxblur的值,计算这个的优化方式和Boxblur又是相同的,一环套一环,当然这个时候的速度会比上面的慢一点,因此公共的计算不能重复利用了,大概需要17ms。

  更广泛的讲,还可以用上述方式计算任意两幅图像的局部平方差,速度和效率同样很高。比如计算原图和高斯模糊后的图的局部平法差,会得到什么结果呢?

  使用这种方式优化后,我以前提的磨皮算法针对1080P的图可以做到约20ms每帧,而且效果非常好,完全可以使用到视频处理中。

  参考效果下载:,见其中的Boxblur - >LeeAddtiveNoiseFilter 以及Enhance ->MakeUp和ImageInfo->Stdfilter等。

 

 

转载于:https://www.cnblogs.com/Imageshop/p/8321886.html

你可能感兴趣的文章
【转载】pygame的斜线运动
查看>>
How to measure IOPS for VMware
查看>>
GNU风格 ARM汇编语法4
查看>>
poj2148
查看>>
jQuery实现侧边导航栏效果
查看>>
javascript使浏览器关闭前弹出确认
查看>>
apache 启动不了
查看>>
为什么晋升的不是你?
查看>>
给SharePoint页面加入自己定义页脚Custom footer
查看>>
Android 布局之LinearLayout 子控件weight权重的作用详析
查看>>
MVC 5 的 EF6 Code First 入门
查看>>
我的Eclipse快捷键.
查看>>
Codeforces Round #248 (Div. 1) B. Nanami's Digital Board 暴力 前缀和
查看>>
工作中常用的英文单词缩写
查看>>
bufferedReader 乱码问题
查看>>
Ubuntu16.04最快捷搭建小型局域网Git服务器
查看>>
Android--去除EditText边框,添加下划线,
查看>>
MapReduce类型与格式(输入与输出)
查看>>
SQL Server存储过程中使用表值作为输入参数示例
查看>>
如何设置ASP.NET页面的运行超时时间 (转载)
查看>>