频域滤波中默认的边界条件——补零与不补零(答作者问)

这个问题源自于Rafael Gonzalez的《数字图像处理》中的这幅图,为什么他频域滤波要将图像零延拓到二倍尺寸?

完全没有没要,既浪费计算,又浪费空间。

廖老师的问题是图像滤波涉及到源图像和滤波器相卷,卷积结果尺寸要大于源图像尺寸,因此要考虑边界处图像卷积处理,而通过延拓扩大的源图像对应的频域变换也就发生了相应变化。不同的延拓,对应的频域变换也是不一样的。

答:如果 M M M点信号与 N N N点冲激响应卷积,对于线性卷积而言,那结果的长度是 M + N − 1 M+N-1 M+N1,如果要完全线性卷积,那就是需要补零延拓。然而对图像来说,我们通常需要滤波后结果与滤波前图像尺寸相同。所以,不用补零也可以,只是默认周期延拓,我更偏向于这样的结果。零延拓不会影响频谱(DTFT),而延拓也不是可选择的,是默认的。
在这里插入图片描述
注:图(d)错误,见这里
这个他给的解释,并没有从理论高度做解释。
在这里插入图片描述

三个基础知识

卷积边界延拓的方式

在这里插入图片描述

离散傅里叶变换的周期性

在这里插入图片描述

线性卷积和循环卷积等效的条件

在这里插入图片描述

离散傅里叶变换的卷积定理

循环卷积对应于离散傅里叶变换的乘积,即离散傅里叶变换的卷积定理。

如果 X ( k ) = D F T { x ( n ) } X(k) = DFT\{x(n)\} X(k)=DFT{x(n)} Y ( k ) = D F T { y ( n ) } Y(k) = DFT\{y(n)\} Y(k)=DFT{y(n)},那么

X ( k ) Y ( k ) = D F T { { x ( n ) } ⊛ { y ( n ) } } X(k)Y(k) = DFT\{\{x(n)\} \circledast \{y(n)\}\} X(k)Y(k)=DFT{{x(n)}{y(n)}}

这里, ⊛ \circledast 表示由下式定义的循环卷积:

{ x ( n ) } ⊛ { y ( n ) } = ∑ m = 0 N − 1 x ( m ) y ( ( n − m ) m o d    N ) . \{x(n)\} \circledast \{y(n)\} = \sum_{m=0}^{N-1} x(m)y((n-m) \mod N). {x(n)}{y(n)}=m=0N1x(m)y((nm)modN).

y ( ( n − m ) m o d    N ) y((n-m) \mod N) y((nm)modN)表示循环移位。

Conventional Shift

在这里插入图片描述

Circular Shift

在这里插入图片描述

线性卷积是这样的, h ( − n ) h(-n) h(n)移位,计算与 f ( n ) f(n) f(n)对位相乘再求和,一直下去就是线性卷积的结果 g ( n ) g(n) g(n)
在这里插入图片描述

然而,不幸的是,离散傅里叶变换的周期性造成时域是循环卷积。某人优点很突出,缺点也很突出,我很欣赏他的优点,怎么办呢?那只能解决掉他的缺点。

零延拓,补零的边界条件

循环卷积没办法了,那就想办法让循环卷积与线性卷积等价,于是就有了零延拓。对信号补零到线性卷积结果的长度。图中虽然循环移位,但是由于信号 f ( n ) f(n) f(n)补零了,对应的那两个点就是零,相乘也是零。换句话说就是把位置给留出来。这样仍然是线性卷积的结果。
在这里插入图片描述

由于是线性卷积,那默认的边界延拓方式就是零延拓。看图说话,相当于 f ( n ) f(n) f(n)补零后周期延拓, h ( − n ) h(-n) h(n)移位,那就是零延拓的线性卷积。
在这里插入图片描述

看图像的结果,这里看不出大小。

在这里插入图片描述
因为fft2本身可以做任意点的傅里叶变换,所以无需提前延拓,也就没显示。
在这里插入图片描述
在这里插入图片描述

空域滤波器,频域实现。

blurtype = 'gaussian';
sigma = 2;
hsize = 2 * ceil(3 * sigma) + 1;
psf_gauss = fspecial('gaussian', hsize, sigma);
offset = floor(size(psf_gauss)/2);
S = size(Img) + size(psf_gauss) - 1;
F = fft2(Img, S(1), S(2));
H = fft2(psf_gauss, S(1), S(2));

G=F.* H;
g=im2uint8(real(ifft2(G)));

那Gonzalez为什么要补零为二倍呢?这是由于他在频域直接对模拟滤波器采样为 M × N M\times N M×N点,对应的空域就是 M × N M\times N M×N点(频域滤波器不这样设计,很离谱,暂且不论)。所以为了不产生混叠,延拓的图像尺寸至少是 ( 2 M − 1 ) × ( 2 N − 1 ) (2M-1)\times (2N-1) (2M1)×(2N1)。他的大错不少,小错不断,他认为是 2 M × 2 N 2M \times 2N 2M×2N也就见怪不怪了。

频域滤波器

在这里插入图片描述

filename = 'cameraman';
suffix = '.tif';
Img = im2double(im2gray(imread([filename, suffix])));
[M,N]=size(Img);
D0 = 0.15;
[U,V] = freqspace([2*M 2*N],'meshgrid');
d = sqrt(U.^2+V.^2);
H = exp(-(d/(2*D0.^2)));

F = fftshift(fft2(Img,2*M,2*N));
G = F.* H;
g=im2uint8(real(ifft2(ifftshift(G))));

不补零,周期延拓的边界条件

回头再看不零延拓的话,会怎么样?头部数据混叠,尾部数据丢失。
在这里插入图片描述

但是图像处理的滤波通常是考虑same size的结果,可以先做循环移位。
在这里插入图片描述

在这里插入图片描述
与线性卷积的结果比较,中间的五个值是相同的,这是因为边界受周期延拓影响了。

>> gc

gc =

    1.4641    1.5738    0.9545    0.5790    0.3512    0.2130    0.8149
>> g

g =

    0.7071    1.4289    1.5738    0.9545    0.5790    0.3512    0.2130    0.1078    0.0352


所以MATLAB提出了psf2otf函数,先做循环移位,再计算离散傅里叶变换。如果有空域的卷积核,通过这个函数实现频域滤波。相当于周期延拓的边界条件。

空域滤波器,频域实现。

在这里插入图片描述

[M,N]=size(Img);
F = fft2(Img,M,N);

blurtype = 'gaussian';
sigma = 2;
hsize = 2 * ceil(3 * sigma) + 1;
offset = (hsize-1)/2;
psf_gauss = fspecial('gaussian', hsize, sigma);
H = psf2otf(psf_gauss, [M,N]); %这里使用fft2就会产生错误,很多刊物这里有误。
G=F.*H;
g=im2uint8(real(ifft2(G)));

注意psf2otf的地方。

频域滤波器

在这里插入图片描述

[M,N]=size(Img);
D0 = 0.3;
[U,V] = freqspace([M N],'meshgrid');
d = sqrt(U.^2+V.^2);
H = exp(-(d/(2*D0.^2)));

F = fftshift(fft2(Img));
G = F.* H;

g=im2uint8(real(ifft2(ifftshift(G))));

结论

完全没有必要延拓,可以对原图像尺寸的频率直接频域滤波或者频域实现,就是相当于周期延拓。本来空域也有这样的延拓方式,而且我觉得比零延拓的效果好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值