zoukankan      html  css  js  c++  java
  • 图像处理界双线性插值算法的优化

      在图像处理中,双线性插值算法的使用频率相当高,比如在图像的缩放中,在所有的扭曲算法中,都可以利用该算法改进处理的视觉效果。首先,我们看看该算法的简介。

         在数学上,双线性插值算法可以看成是两个变量间的线性插值的延伸。执行该过程的关键思路是先在一个方向上执行线性插值,然后再在另外一个方向上插值。下图示意出这个过程的大概意思。

         用一个简单的数学表达式可以表示如下:

         f(x,y)=f(0,0)(1-x)(1-y)+f(1,0)x(1-y)+f(0,1)(1-x)y+f(1,1)xy

         合并有关项,可写为: f(x,y)=(f(0,0)(1-x)+f(1,0)x) (1-y)+(f(0,1)(1-x)+f(1,1)x)y

         由上式可以看出,这个过程存在着大量的浮点数运算,对于图像这样大的计算用户来说,是一个较为耗时的过程。

         考虑到图像的特殊性,他的像素值的计算结果需要落在0到255之间,最多只有256种结果,由上式可以看出,一般情况下,计算出的f(x,y)是个浮点数,我们还需要对该浮点数进行取整。因此,我们可以考虑将该过程中的所有类似于1-x、1-y的变量放大合适的倍数,得到对应的整数,最后再除以一个合适的整数作为插值的结果。

          如何取这个合适的放大倍数呢,要从三个方面考虑,第一:精度问题,如果这个数取得过小,那么经过计算后可能会导致结果出现较大的误差。第二,这个数不能太大,太大会导致计算过程超过长整形所能表达的范围。第三:速度考虑。假如放大倍数取为12,那么算式在最后的结果中应该需要除以12*12=144,但是如果取为16,则最后的除数为16*16=256,这个数字好,我们可以用右移来实现,而右移要比普通的整除快多了。 

          综合考虑上述三条,我们选择2048这个数比较合适。

          下面我们假定某个算法得到了我们要取样的坐标分别PosX以及PosY,其中PosX=25.489,PosY=58.698。则这个过程的类似代码片段如下:

     1 NewX = Int(PosX)                        '向下取整,NewX=25
     2 NewY = Int(PosY)                        '向下取整,NewY=58
     3 PartX = (PosX - NewX) * 2048            '对应表达式中的X
     4 PartY = (PosY - NewY) * 2048            '对应表达式中的Y
     5 InvX = 2048 - PartX                     '对应表达式中的1-X
     6 InvY = 2048 - PartY                     '对应表达式中的1-Y
     7 
     8 Index1 = SamStride * NewY + NewX * 3    '计算取样点左上角邻近的那个像素点的内存地址
     9 Index2 = Index1 + SamStride          '左下角像素点地址
    10 ImageData(Speed + 2) = ((Sample(Index1 + 2) * InvX + Sample(Index1 + 5) * PartX) * InvY + (Sample(Index2 + 2) * InvX + 
                              Sample(Index2 + 5) * PartX) * PartY) \ 4194304       '处理红色分量
    11 ImageData(Speed + 1) = ((Sample(Index1 + 1) * InvX + Sample(Index1 + 4) * PartX) * InvY + (Sample(Index2 + 1) * InvX +
                              Sample(Index2 + 4) * PartX) * PartY) \ 4194304       '处理绿色分量
    12 ImageData(Speed) = ((Sample(Index1) * InvX + Sample(Index1 + 3) * PartX) * InvY + (Sample(Index2) * InvX +
                          Sample(Index2 + 3) * PartX) * PartY) \ 4194304           '处理蓝色分量

          以上代码中涉及到的变量都为整型(PosX及PosY当然为浮点型)。

          代码中Sample数组保存了从中取样的图像数据,SamStride为该图像的扫描行大小。

          观察上述代码,除了有2句涉及到了浮点计算,其他都是整数之间的运算。

          在Basic语言中,编译时如果勾选所有的高级优化,则\ 4194304会被编译为>>22,即右移22位,如果使用的是C语言,则直接写为>>22。

          需要注意的是,在进行这代代码前,需要保证PosX以及PosY在合理的范围内,即不能超出取样图像的宽度和高度范围。

          通过这样的改进,速度较直接用浮点类型快至少100%以上,而处理后的效果基本没有什么区别。

          共享一段利用该方式处理图像缩放的程序:https://files.cnblogs.com/Imageshop/VBScale.rar

      

  • 相关阅读:
    Ceph中的容量计算与管理
    Ceph Monitor基础架构与模块详解
    Ceph:pg peering过程分析
    API调用过程
    Windows内核—保护模式
    逆向笔记——C、C++对应的汇编结构(一)
    2020年内网渗透培训:红队攻防
    2020年 初级渗透工程师【Web安全方向】
    渗透测试【网络安全】入门指南【20190607】
    渗透学习问题【一】遇到坑需要停下来补吗
  • 原文地址:https://www.cnblogs.com/Imageshop/p/2246808.html
Copyright © 2011-2022 走看看