首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何消除在fft中由于零填充而产生的边界效应?

如何消除在fft中由于零填充而产生的边界效应?
EN

Stack Overflow用户
提问于 2012-04-04 06:39:02
回答 2查看 7.1K关注 0票数 6

我用Weierstrass变换做了一个python代码来平滑给定的信号,这基本上是一个正态高斯和信号的卷积。

守则如下:

代码语言:javascript
运行
复制
#Importing relevant libraries  
from __future__ import division  
from scipy.signal import fftconvolve   
import numpy as np 

def smooth_func(sig, x, t= 0.002):   
    N = len(x)   
    x1 = x[-1]   
    x0 = x[0]    


# defining a new array y which is symmetric around zero, to make the gaussian symmetric.  
    y = np.linspace(-(x1-x0)/2, (x1-x0)/2, N)   
    #gaussian centered around zero.  
    gaus = np.exp(-y**(2)/t)     

#using fftconvolve to speed up the convolution; gaus.sum() is the normalization constant.  
    return fftconvolve(sig, gaus/gaus.sum(), mode='same')

如果我运行这个代码来表示一个step函数,它会平滑拐角处,但是在边界处它会解释另一个拐角,也会平滑它,从而在边界上产生不必要的行为。我用下面的链接中所示的数字来解释这一点。

边界效应

如果我们直接积分以求卷积,这个问题就不会出现。因此,问题不是在Weierstrass变换中,而是在参数的函数变换中。

要理解为什么会出现这个问题,我们首先需要了解“投入”中的“转移”的工作原理。

函数主要利用卷积定理来加快计算速度。

简而言之,它说:

卷积(int1,int2)=ifft(fft(int1)*fft(int2))

如果我们直接应用这个定理,我们就得不到预期的结果。为了得到想要的结果,我们需要对一个最大的两倍大小的阵列(int1,int2)进行快速傅立叶变换。但这会导致不理想的边界效应。这是因为在fft代码中,如果大小(Int)大于大小(用于进行fft),则将输入为零,然后取fft。这种零填充正是造成不想要的边界效应的原因。

你能建议一种消除这种边界效应的方法吗?

我试着用一个简单的技巧把它移除。在平滑函数之后,我将平滑信号的值与边界附近的原始信号进行组合,如果它们不匹配,则将平滑函数的值替换为输入信号。

其内容如下:

代码语言:javascript
运行
复制
i = 0 
eps=1e-3
while abs(smooth[i]-sig[i])> eps: #compairing the signals on the left boundary
    smooth[i] = sig[i]
    i = i + 1
j = -1

while abs(smooth[j]-sig[j])> eps: # compairing on the right boundary.
    smooth[j] = sig[j]
    j = j - 1

这种方法有一个问题,因为使用epsilon,在平滑的函数中有小的跳跃,如下所示:

在光滑的漏斗中跳跃

,上面的方法有什么变化来解决这个边界问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-04-06 00:32:27

对称过滤器内核在端产生什么取决于假设数据是否超出了端点。

如果您不喜欢当前结果的外观(在两端都假设为零),那么尝试用另一个假设扩展数据,比如数据的反射,或者多项式回归延拓。将两端的数据至少扩展一半的过滤内核长度(除非您的扩展是零,这是免费的现有的零填充所需的非圆卷积)。然后,删除过滤后添加的结束导出,并查看您是否喜欢您的假设的外观。如果没有,尝试另一个假设。或者更好的是,如果你有这样的数据的话,就使用实际的数据。

票数 3
EN

Stack Overflow用户

发布于 2012-04-04 09:16:02

最好的方法可能是使用mode = 'valid'

The output consists only of those elements that do not rely on the zero-padding.

除非您可以包装您的信号,或者正在处理的信号是从更大的信号中摘录出来的(在这种情况下:处理完整的信号然后裁剪感兴趣的区域),在进行卷积时总是会产生边缘效应。你必须选择你想如何对付他们。使用mode = valid只需将其裁剪掉,这是一个很好的解决方案。如果你知道信号总是‘步形’,那么你就可以适当地扩展处理后的信号的前端和末端。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10006084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档