我用Weierstrass变换做了一个python代码来平滑给定的信号,这基本上是一个正态高斯和信号的卷积。
守则如下:
#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。这种零填充正是造成不想要的边界效应的原因。
你能建议一种消除这种边界效应的方法吗?
我试着用一个简单的技巧把它移除。在平滑函数之后,我将平滑信号的值与边界附近的原始信号进行组合,如果它们不匹配,则将平滑函数的值替换为输入信号。
其内容如下:
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,在平滑的函数中有小的跳跃,如下所示:
,上面的方法有什么变化来解决这个边界问题吗?
发布于 2012-04-06 00:32:27
对称过滤器内核在端产生什么取决于假设数据是否超出了端点。
如果您不喜欢当前结果的外观(在两端都假设为零),那么尝试用另一个假设扩展数据,比如数据的反射,或者多项式回归延拓。将两端的数据至少扩展一半的过滤内核长度(除非您的扩展是零,这是免费的现有的零填充所需的非圆卷积)。然后,删除过滤后添加的结束导出,并查看您是否喜欢您的假设的外观。如果没有,尝试另一个假设。或者更好的是,如果你有这样的数据的话,就使用实际的数据。
发布于 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
只需将其裁剪掉,这是一个很好的解决方案。如果你知道信号总是‘步形’,那么你就可以适当地扩展处理后的信号的前端和末端。
https://stackoverflow.com/questions/10006084
复制相似问题