したがって、FFTによる畳み込みは、実空間での畳み込みよりも計算の複雑さが低いことを認識しています。しかし、FFT畳み込みの欠点は何ですか?
カーネルサイズは常にイメージサイズと一致する必要がありますか、それとも、たとえばpythons numpyおよびscipyパッケージで、これを処理する関数がありますか?そして、アンチエイリアシング効果はどうですか?
FFT畳み込みは、 畳み込み定理 に基づいています。これは、Fd()
とFi()
の場合、2つの関数f
とg
を与えることを示しています。直接および逆フーリエ変換、および*
および.
の畳み込みと乗算を示し、次のようになります。
f*g = Fi(Fd(d).Fd(g))
これをシグナルf
とカーネルg
に適用するには、次の点に注意する必要があります。
f
とg
のサイズが同じである必要があるため、カーネルをゼロパッドする必要があります。信号とカーネルのサイズがf_l
とg_l
の場合、時間領域で単純な畳み込みを行うには、g_l * (f_l - g_l + 1)
の乗算と(g_l - 1) * (f_l - g_l + 1)
の加算が必要です。
FFTアプローチの場合、少なくともf_l + g_l
のサイズの3つのFFTと、f_l + g_l
の乗算を実行する必要があります。
f
とg
の両方のサイズが大きい場合、FFTはn*log(n)
の複雑さで明らかに優れています。小さなカーネルの場合、直接的なアプローチの方が速い場合があります。
scipy.signal
には、 convolve
と fftconvolve
の両方のメソッドがあります。また、fftconvolve
は、上記のすべてのパディングを透過的に処理します。
高速畳み込みは、直接形式の畳み込みよりも「大きなO」の複雑さが優れています。いくつかの欠点または警告があります。私はこのトピックについていくつか考えました 記事 しばらく前に書きました。
「ビッグO」の複雑さが優れていると、必ずしも優れているとは限りません。直接フォーム畳み込みは、特定のサイズよりも小さいフィルターにFFTを使用するよりも高速です。正確なサイズは、使用するプラットフォームと実装によって異なります。クロスオーバーポイントは通常、10〜40の係数範囲にあります。
レイテンシー。高速畳み込みは本質的にブロック単位のアルゴリズムです。変換する前に一度に数百または数千のサンプルをキューに入れることは、一部のリアルタイムアプリケーションでは受け入れられない場合があります。
実装の複雑さ。直接形式は、メモリ、コードスペース、およびライター/メンテナの理論的背景の点で単純です。
固定小数点DSPプラットフォーム(汎用CPUではない)の場合:固定小数点FFTのワードサイズに関する考慮事項が限られているため、大きな固定小数点FFTはほとんど役に立たなくなります。サイズスペクトルのもう一方の端では、これらのチップには、直接形式のFIR計算を実行するために適切に設計された特殊なMAC命令があり、O(N ^ 2)直接形式がO(NlogN)よりも高速である範囲が広がります。これらの要因は、固定小数点FFTが高速畳み込みに役立つ限られた「スイートスポット」を作成する傾向があります。