工程及源代码:快速模糊.rar
图像模糊算法有很多种,我们最常见的就是均值模糊,即取一定半径内的像素值之平均值作为当前点的新的像素值,在一般的工业应用中常取3*3的模板,这种小模板为了提高速度,可以直接把两层小的循环展开为表达式。但是在图像的艺术处理上,常用到比较大的半径,这时一来展开计算不现实,而来用两层循环会大大降低速度,三则半径越大,计算速度也就越慢,因此,必须寻找到一种快速实现这种效果的算法,在均值模糊这种比较特殊的情况下,用懒惰算法也许是非常有效而又简单的实现手段了。
在均值模糊中,在计算前一个像素点结果的过程中,涉及到了其周围r*r个像素的累计和,而在计算下一个像素点的过程中,将会有 (r-1)*(r-1)个周围点和前一次的重合(不考虑边缘点),因此,如果我们能恰当利用这些重合的信息,则在计算的过程中就可以有效的降低计算量,并且这种特性使得模糊计算的时间和半径的关系基本不敏感了。
考虑到边缘像素的一些情况,我们的计算可以分为三个阶段。
第一步:计算图像最左上角的像素的结果值,并记录下记录下各颜色分量的累加和以及有效像素数。
For X = 0 To Rad '循环无需从-Rad to Rad ,因为我们明确知道在-Rad到0处图像无数据
For y = 0 To Rad '计算左上角第一个像素的模糊化值,记录下各颜色分量和有效像素数
pDataArrC(0) = mPtrc + mWidthBytes * y + X * 4 '指向我们需要的数句在备份数据中的地址(首地址+高度*扫描行宽度+宽度*每像素字节数)
SumRed(0) = SumRed(0) + DataArrC(2) '累加值
SumGreen(0) = SumGreen(0) + DataArrC(1)
SumBlue(0) = SumBlue(0) + DataArrC(0)
SumNum(0) = SumNum(0) + 1 '计数器加一
Next
Next
For y = 0 To Rad '计算左上角第一个像素的模糊化值,记录下各颜色分量和有效像素数
pDataArrC(0) = mPtrc + mWidthBytes * y + X * 4 '指向我们需要的数句在备份数据中的地址(首地址+高度*扫描行宽度+宽度*每像素字节数)
SumRed(0) = SumRed(0) + DataArrC(2) '累加值
SumGreen(0) = SumGreen(0) + DataArrC(1)
SumBlue(0) = SumBlue(0) + DataArrC(0)
SumNum(0) = SumNum(0) + 1 '计数器加一
Next
Next
第二步: 计算第一行像素除中除(0,0)点外其他像素的模糊值,这一步就要充分利用第一步的信息。
这一步的代码详见工程。
第三步,在计算出图像中第一行的基础上,一次计算出下面各行的模糊值,这里有一些信息的移出和移入的操作,还有边缘操作的一些事项要注意。
注意,我的工程中把图像数据的起点修正为屏幕的左上角,这样做是为了和GDI的坐标系统一,在很多时候这样做都会带来方便的。
在高斯模糊中,我们也可以用类似的方法对算法进行优化,这个可以参考paint.net的代码。