Gauss滤波的快速实现方法
二维高斯函数具有旋转对称性,处理后不会对哪一个方向上的边缘进行了过多的滤波,因此相对其他滤波器,具有无法比拟的优越性。但是传统Gauss滤波随着图像尺寸的增加,运算复杂度呈平方上涨,因此需要对其优化改进。下面,分别介绍传统型,分解型和递归迭代型三种实现方法。
1 传统型
Gauss滤波首先需要构建一个Gauss滤波核,公式为:
Matlab实现代码:
dSigma =0.8; fK1=1.0/(2*dSigma*dSigma); fK2=fK1/pi; iSize = 5; step = floor(iSize/2 + 0.5); for i = 1 : iSize x=i-step; fTemp=fK2*exp(-x*x*fK1); for j = 1 : iSize y=j-step; model(x+step,y+step)=fTemp*exp(-y*y*fK1); end end dSum = sum(sum(model)); model = model/dSum; %Gauss核数值归一化
图1 Gauss滤波核(5*5大小)
接下来就是将输入图像和滤波核进行卷积操作。其实质就是对原始图像进行加权求和,把这个“和”赋给中心像素。对于一个2048*2048的图像,需要进行104734756次乘法运算,和104734756次加法运算,运算复杂度是很高的。
2 分解型
我们可以把一个二维Gauss核分解为两个一维高斯核,然后先对行做一次一维卷积,再对这个卷积结果做一次一维列卷积,得到的结果完全一模一样,而开销会小很多。
一维高斯核函数:
Matlab代码实现:
dSigma =0.8; fK1=1.0/(2*dSigma*dSigma); fK2=fK1/pi; iSize = 5; step = floor(iSize/2 + 0.5); for i = 1 : iSize x=i-step; fTemp=fK2*exp(-x*x*fK1); model(1,x+step) = fTemp; end dM = sum(model); model = model / dM;
图2 一维高斯滤波核(1*5大小)
一维卷积原理和二维卷积一样,只不过我们只需要将同一行或同一列上的数据,按位置一一加权求和,再把“和”赋给中心元素。
对于一个2048*2048的图像,需要进行41918464次乘法运算,和41918464次加法运算。相比传统运算量,只是前者的1/2.4985。如果遇到频繁计算Gauss滤波的算法,后者明显比前者速度快很多。
3 递归迭代型
第二种方法较第一种方法,虽然有了较大改善,但是任然复杂度较高。这里再介绍一种更快速的逼近Gauss滤波方法。
具体步骤分为两步:首先对图像做一次前向滤波,其次,对图像再做一次后向滤波。
Forward:
Backward:
参考资料:Recursive implementation of the Gaussian filter。 Ian T. Young,1995