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

news/2024/12/12 14:52:51/

这个问题源自于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的结果,可以先做循环移位。
在这里插入图片描述

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

>> gcgc =1.4641    1.5738    0.9545    0.5790    0.3512    0.2130    0.8149
>> gg =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))));

结论

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


http://www.ppmy.cn/news/1554524.html

相关文章

5分钟入门SpringAi - java快速接入国内大模型

本文的协作目的是帮你怎样用Spring AI给Java项目加上通义千问的AI功能。 会从设置环境讲到写代码的具体步骤。 例子使用的是spring ai alibaba和QWen千问API。你可以先试着跑通例子,再换成自己的实现。 现在QWen有100万免费Token可以用,很适合快速开发…

Spring Boot 集成阿里云OSS 完成文件上传下载

前言: 文件上传下载在项目开发中是一个非常常见的业务场景,在云服务上还没有兴起的时候,一般来说都会把文件单独存放到文件服务器上,随着云服务的兴起,各类云服务厂商都提供了 OSS 服务,本篇我们分享 Spri…

嵌入式蓝桥杯学习6 定时中断按键(短按 长按 双击)

前面的cubemx配置都和定时中断的一样,详情请看上文,这篇我们主要写按键相关的代码。 前面的外部中断的按键,还有直接写的按键函数都不适用于比赛,各有不同缺点。在比赛中按键又是个很重要的外设,那如何实现按键呢&…

【Android】车芯 | 使用HTP运行设备端模型

首先,确保运行在设备的模型制作过程以及host端验证已完成啦。模型制作过程可参考:【qualcomm】QNN SDK的下载以及运行在设备端的模型制作-CSDN博客 本文以之前生成的Resnet18_quantized.bin作为测试模型。 1 新建文件夹/data/test

Socks5机房代理IP的测试与挑选指南

选择合适的代理IP不仅能够提升您的网络体验,还能够保护您的个人信息和数据安全,让您更加安心地畅游互联网世界。因此如何测试和挑选合适的代理IP就显得尤为重要。本文将为您详细介绍测试和挑选方法。 1. 确定测试指标 在测试和挑选之前,首先…

单片机:实现贪吃蛇(附带源码)

单片机实现贪吃蛇游戏是一个较为复杂的项目,涉及到硬件控制、程序设计、图形显示、输入处理等方面。这里我们以基于8051单片机为例,详细介绍如何通过硬件和软件来实现一个简单的贪吃蛇游戏。为了让解释更加清晰,我们将逐步分析贪吃蛇的游戏逻…

RPO: Read-only Prompt Optimization for Vision-Language Few-shot Learning

文章汇总 想解决的问题 对CoOp的改进CoCoOp尽管提升了性能,但却增加了方差(模型的准确率波动性较大)。 模型的框架 一眼看去,跟maple很像(maple跟这篇文章都是2023年发表的),但maple的视觉提示是由文本提示经过全连接…

深度学习笔记之BERT(五)TinyBERT

深度学习笔记之TinyBERT 引言回顾:DistilBERT模型TinyBERT模型结构TinyBERT模型策略Transformer层蒸馏嵌入层蒸馏预测层蒸馏 TinyBERT模型的训练效果展示 引言 上一节介绍了 DistilBERT \text{DistilBERT} DistilBERT模型,本节将继续介绍优化性更强的知…