这是一个对简短问题的详细回答。如果想要学到更多,可以阅读下面的内容。
低通滤波器和高通滤波器都是线性滤波器。
线性滤波器可以在空间域通过卷积应用,也可以在频率域(即傅里叶域)中作为乘法应用。
事实上,在傅里叶域中,低通滤波器核与全通滤波器之间的差异就是高通滤波器:
high_pass_filter = identity_filter - low_pass_filter
身份过滤器是每个元素都为1的内核。通过乘法应用滤波器,因此
IM2 * high_pass_filter = IM2 * ( identity_filter - low_pass_filter )
这与
IM2 * high_pass_filter = IM2 - IM2 * low_pass_filter
在这里,与问题中一样,
IM2
是图像
im2
的傅里叶域表示;所有黄色边框中的内容都是指方程,但使用伪代码编写,并使用
*
符号表示乘法。
因此,OP希望在傅里叶域中应用低通滤波器并减去输入图像,以获得高通滤波后的图像。
然而,傅里叶变换的一个
基本属性是它是线性变换。这意味着:
F(a*f + b*g) == a * F(f) + b * F(g)
(其中F(。)
为傅里叶变换,a
和b
是常数,f
和g
是函数)。设置a = 1
和b = -1
,并将g
设置为低通滤波后的图像,将f
设置为输入图像,我们得到
F(im2 - im2_low) == F(im2) - F(im2_low)
也就是说,在空间域和傅里叶域中的减法是等效的。因此,如果在空间域中计算im2_low
,则无需转到傅里叶域进行减法。这两个代码段产生相同的结果(精度上略有差异):
F = fft2(im2_low);
IM2 = fft2(im2);
IM2_high = IM2 - F;
im2_high = ifft2(IM2_high);
im2_high = im2 - im2_low;
此外,卷积也是线性的。这意味着,如果您将上述方程中的
F(.)
视为卷积,则这些方程仍然成立。您可以进行以下操作:
conv(f, h) - f == conv(f, h) - conv(f, 1) == conv(f, h-1)
这直接导致了空间域中高通滤波器的定义:
g = - compute_kernel(9,101);
g(51,51) = g(51,51) + 1;
im2_high2 = conv2(im2,g,'same');
您会发现
max(max(abs(im2_high-im2_high2)))
得出的值非常接近0。
关于计算高斯滤波的注意事项:
本问题中发布的
compute_kernel
函数通过直接计算2D高斯来计算2D滤波器内核。生成的滤波器内核为101x101像素,这意味着计算卷积需要
101*101*N
个乘加操作(MADs),其中N是过滤图像中的像素数。然而,高斯滤波是可分离的,这意味着可以仅用
101*2*N
个MAD(少50倍!)获得相同的结果。此外,对于
sigma=9
,也可以使用较小的内核。
Gaussian kernel size:
The Gaussian function never reaches zero, but it reaches very close to zero quite quickly. When cutting it off at 3*sigma
, very little of it is lost. I find 3 sigma to be a good balance. In the case of sigma = 9, the 3 sigma cutoff leads to a kernel with 55 pixels (3*sigma * 2 + 1).
Gaussian separability:
The multi-dimensional Gaussian can be obtained by multiplying 1D Gaussians together:
exp(-(y.^2+x.^2)/(2*sigma*sigma)) == exp(-(x.^2)/(2*sigma*sigma)) * exp(-(y.^2)/(2*sigma*sigma))
This leads to a much more efficient implementation of the convolution:
conv(f,h1*h2) == conv( conv(f,h1), h2 )
That is, convolving an image with a column filter h1
and then convolving the result with a row filter h2
is the same as convolving the image with a 2D filter h1*h2
. In code:
sigma = 9;
sizei = ceil(3*sigma);
g = exp(-(-sizei:sizei).^2/(2*sigma.^2));
g = g/sum(g(:));
im2_low = conv2(g,g,im2,'same');
g2d = g' * g;
im2_low2 = conv2(im2,g2d,'same');
The difference is numerical imprecision:
max(max(abs(im2_low-im2_low2)))
ans =
1.3927e-12
你可以在我的博客上找到更详细的高斯滤波描述,还有使用MATLAB图像处理工具箱时可能遇到的一些问题。
点击这里查看有关高斯滤波的更详细说明,点击这里了解使用MATLAB图像处理工具箱时可能会遇到的一些问题。
figure();imshow(im2_low,[]);colorbar;figure();imshow(im2,[]);colorbar;f
。注意颜色条的值。在您的情况下,低通滤波器的值为数千,而原始图像仅到255。如果要保持值的范围,则需要将卷积核归一化为总和为1。 - Ander Bigurifft
和ifft
是多余的。 - Cris Luengo