6

ワイエルシュトラス変換を使用して特定の信号を平滑化するための 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')

このコードをたとえばステップ関数に対して実行すると、角が滑らかになりますが、境界では別の角が解釈されてそれも滑らかになり、結果として境界で不要な動作が発生します。以下のリンクに示されている図でこれを説明します。
境界効果

畳み込みを見つけるために直接積分する場合、この問題は発生しません。したがって、問題は Weierstrass 変換にはないため、問題は scipy の fftconvolve 関数にあります。

この問題が発生する理由を理解するには、まず scipy での fftconvolve の動作を理解する必要があります。
fftconvolve 関数は、基本的に畳み込み定理を使用して計算を高速化します。
convolution( int1
,int2)=ifft(fft(int1)*fft(int2))
この定理を直接適用すると、望ましい結果が得られません。目的の結果を得るには、配列の fft を max(int1,int2) の 2 倍のサイズにする必要があります。しかし、これは望ましくない境界効果につながります。これは、fft コードでは、size(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

イプシロンを使用するため、以下に示すように、平滑化された関数に小さなジャンプがあるため、この方法には問題があります

この境界の問題を解決するために、上記の方法に変更を加えることはできますか?

4

2 に答える 2

7

最良のアプローチは、おそらく使用することmode = 'valid'です:

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

信号をラップできない場合、または処理中の信号がより大きな信号からの抜粋である場合 (この場合: 完全な信号を処理してから対象領域を切り取る) でない限り、畳み込みを行うときに常にエッジ効果が発生します。それらにどのように対処するかを選択する必要があります。を使用mode = validすると、それらが切り落とされます。これは非常に優れたソリューションです。信号が常に「ステップ状」であることがわかっている場合は、処理された信号の前後を適切に拡張できます。

于 2012-04-04T09:16:02.263 に答える
3

対称フィルター カーネルが最後に何を生成するかは、データが最後に何を想定しているかによって異なります。

両端を超えてゼロを想定している現在の結果の外観が気に入らない場合は、データの反映、または多項式回帰の継続など、別の仮定でデータを拡張してみてください。両端のデータをフィルター カーネルの長さの少なくとも半分だけ拡張します (非循環畳み込みに必要な既存のゼロ パディングを無料で使用できる拡張がゼロの場合を除く)。次に、フィルタリング後に追加された end exensions を削除し、仮定の外観が気に入るかどうかを確認します。そうでない場合は、別の仮定を試してください。または、実際のデータがある場合は、それを超えて実際のデータを使用してください。

于 2012-04-06T00:32:27.243 に答える