ImageMagick の例 --
フーリエ変換

目次
ImageMagick の例 序文と目次
はじめに
フーリエ変換
ImageMagickにおけるFFT/IFT
フーリエ変換の特性
実用的な応用
高度な応用
 
FFTの乗算と除算 (低レベルの例 - サブページ)

はじめに

画像処理において理解するのが最も難しい概念の一つは、フーリエ変換です。 これには2つの理由があります。 まず、数学的に高度であること、そして2つ目は、元の画像に似ていない結果の画像を解釈するのが難しいことです。 それでも、フーリエ変換を利用することで、明るさとコントラストの向上、ぼかし、シャープ化、ノイズ除去など、使い慣れた処理を行うための新しい方法を提供できます。 しかし、通常の画像領域ではできない新しい機能も提供できます。 これらには、モーションブラーやレンズのデフォーカスなどの一般的なカメラの歪みの逆畳み込み(デブラーリングとも呼ばれます)と、正規化相互相関を使用した画像マッチングが含まれます。 このページの目的は、フーリエ変換の背景と簡略化された数学を説明し、フーリエ変換を使用して実行できる処理の例を示すことです。 これらが多すぎると思われる場合は、スキップして、ImageMagickにおけるFFT/IFTから始まるプロパティと例に焦点を当てることができます。 興味のある方のために、光学との類似点を含む、もう1つの素晴らしい簡単な説明がフーリエ理論の直感的な説明にあります。 Vanderbilt University School Of Engineeringの講義ノートも、数学的に傾倒している方には非常に有益です。1次元および2次元フーリエ変換周波数フィルタリング。 その他の数学的参考文献には、フーリエ変換離散フーリエ変換高速フーリエ変換、および複素数に関するWikipediaのページが含まれます。 元のデモのコーディングを行ったSean Burkeと、それをImageMagickに統合したImageMagickの作成者に感謝します。どちらも英雄的な努力でした。 多くの例では、変換された画像の精度を維持するために必要なHDRIバージョンのImageMagickを使用しています。 これらの手法を最大限に活用したい場合は、個人のHDRIバージョンをコンパイルすることをお勧めします。

フーリエ変換

画像は通常、「ピクセル」の配列で構成され、それぞれが赤、緑、青、場合によっては透明度などの値のセットによって定義されます。 しかし、ここでは透明度は無視します。 したがって、赤、緑、青の各「チャネル」には、「強度」または「グレースケール」値のセットが含まれています。これは、「空間領域」のラスター画像として知られています。 これは、画像が各「位置」または「空間内の位置」にある「強度値」によって定義されることを示す、単なる派手な言い方です。しかし、画像は「周波数領域」と呼ばれる別の方法でも表すことができます。 この領域では、各画像チャネルは正弦波で表されます。このような「周波数領域」では、各チャネルには、X、Yの「空間」座標ではなく、X、Yの「周波数」に基づいて場所に格納される「振幅」値があります。 これはデジタル表現であるため、周波数は「最小」または単位周波数の倍数であり、ピクセル座標はこの単位周波数のインデックスまたは整数倍を表します。これは、「すべての適切な関数は、正弦波の重ね合わせ(組み合わせまたは合計)によって表すことができる」という原則に従います。 つまり、「周波数領域」表現は、「空間領域」画像を保存および再現する別の方法にすぎません。 しかし、どのように画像を「波」として表すことができるのでしょうか?

画像は波である

任意の画像からピクセルの単一行または列を取り、それをグラフ化すると(スクリプト「im_profile」を使用して「gnuplot」を使用して生成)、それは波のように見えます。

  magick holocaust_tn.gif -colorspace gray miff:- |\
    im_profile -s - image_profile.gif
[IM Output] ==> [IM Output]
変動の間隔と振幅がより規則的であれば、次のような波のパターンに近くなります。

  magick -size 20x150 gradient: -rotate 90 \
          -function sinusoid 3.5,0,.4   wave.gif
  im_profile -s wave.gif wave_profile.gif
[IM Output] ==> [IM Output]
ただし、この規則的な波のパターンは、上記に示した画像プロファイルと漠然と似ていますが、規則的すぎます。 しかし、より多くの波を一緒に追加すると、画像のものにさらに近いパターンを作成できます。

  magick -size 1x150 gradient: -rotate 90 \
          -function sinusoid 3.5,0,.25,.25     wave_1.png
  magick -size 1x150 gradient: -rotate 90 \
          -function sinusoid 1.5,-90,.13,.15   wave_2.png
  magick -size 1x150 gradient: -rotate 90 \
          -function sinusoid 0.6,-90,.07,.1    wave_3.png

  magick wave_1.png wave_2.png wave_3.png \
          -evaluate-sequence add added_waves.png
[IM Output]  + [IM Output]  + [IM Output] ==> [IM Output]
上記の代替例については、バイアスされたグラデーションの追加も参照してください。 この「波の重ね合わせ」(波の追加)ははるかに近いですが、それでも画像パターンと完全に一致しません。 ただし、この方法で続行し、波を追加して調整することで、結果の合成波が元の画像の実際のプロファイルに近づきます。 最終的に、十分な数の波を追加することで、元の画像のプロファイルを正確に再現できます。 これは、数学者ジョセフ・フーリエによって発見されました。 現代的な解釈では、「すべての適切な関数は正弦波の重ね合わせによって表すことができる」と述べています。 つまり、適切な周波数と振幅の正弦波を十分な数だけ加算することで、任意の変動パターンを再現できます。 したがって、「周波数領域」表現は、「空間領域」画像を保存および再現する別の方法にすぎません。 「フーリエ変換」とは、上記の例で行ったように、画像を構成する「波」を解明するプロセスです。

画像における2次元波

上記は、複数の正弦波で画像の単一行のプロファイルを近似する方法の一例を示しています。 ただし、画像は2次元であるため、「周波数領域」で画像を表すために使用される波も2次元である必要があります。 これは、そのような2次元波の一例です。 波にはいくつかのコンポーネントがあります。 画像例

ImageMagickにおけるFFT/IFTの使い方

実装に関する注意事項

ImageMagickは、画像を浮動小数点値(複素数)に変換する必要があるFFTW、離散フーリエ変換ライブラリを使用しており、IMバージョン6.5.4-3で初めて実装されました。 画像に一般的に期待されるように動作させるために、正方形でない画像または奇数次元を持つ画像は、画像の最大幅または高さの正方形になるようにパディングされます(仮想ピクセルを使用)。 「FFT原点」を画像の中心に適切に配置できるように、偶数(2の倍数)の次元を持つように強制されます。 この結果、逆フーリエ変換を適用した後、パディングを削除するために画像を元の寸法にトリミングする必要があります。 フーリエ変換は「複素数」で構成されているため、変換の結果を直接視覚化することはできません。 したがって、複素変換は、2つの形式のいずれかで2つのコンポーネント画像に分割されます。
[Diagram]
複素数
実数部/虚数部

実数部と虚数部

複素数」の通常の数学的および数値的表現は、「実数部」(a)と「虚数部」(b)のコンポーネントで構成される浮動小数点値のペアです。 残念ながら、これら2つの数値には負の値が含まれている可能性があるため、表示可能な画像を形成しません。 そのため、この表現は、そのような画像をクリップする通常のImageMagickでは使用できません(結果の効果の以下の例を参照)。 ただし、HDRIバージョンのImageMagickを使用すると、フーリエ変換された画像のこの表現を生成、使用、さらには保存することもできます。 それらは、それ自体では画像として有用または表示可能ではない場合がありますが、それでも多くの数学演算を適用できます。 この表現を生成するには、演算子の「プラス」形式である "+fft" および "+ift" を使用します。これについては、以下の実数部・虚数部としてのFFTで詳しく説明します。
[Diagram]
複素極座標
強度/位相

強度と位相

画像処理において、「複素数」を直接数値表現する方法はあまり有用ではありません。しかし、値を2次元平面にプロットすることで、値を「振幅」(r)と「位相」(θ)成分からなる極座標表現に変換できます。この形式は画像処理、特に振幅成分において非常に役立ちます。振幅成分は、画像を構成するすべての周波数を本質的に指定します。振幅成分は正の値のみを含み、画像値に直接マッピングされます。値の固定範囲はありませんが、DCまたはゼロ周波数の色を除いて、値は一般的に非常に小さくなります。その結果、振幅画像は一般的に非常に暗く(実際には黒く)見えます。視覚的な詳細を引き出すには、通常、振幅をスケーリングし、その強度値にログ変換を適用する必要があります。結果として得られる「ログ変換された」振幅画像は、画像の「スペクトル」として知られています。ただし、逆変換には「スペクトル」画像ではなく、「振幅」画像を使用する必要があることに注意してください。画像の中心「原点」に表示されるDC(「直流」の略)または「ゼロ周波数」の色は、画像全体の平均色値になります。また、入力画像には「虚数」成分が含まれていないため、DC位相値は常にゼロ位相になり、純粋なグレーの色が生成されます。ただし、位相成分の範囲は-πから+πです。これは最初に0から2πの範囲にバイアスされ、次にコンパイル時メモリ品質によって決定される0から*QuantumRange*までの実際の画像値にスケーリングされます。この結果、ゼロ位相は純粋なグレー値(各チャネルに適切な値)を持ち、負の位相は純粋な黒( '0')値になります。純粋な白( '*QuantumRange*')はほぼ同じですが、完全に同じではありません。画像の振幅と位相FFT表現は、通常のFFT演算子「+fft」と「+ift」を使用して生成されます。これは、最初にFFT画像とその逆変換の生成で検討します。

FFT画像とその逆変換の生成
(振幅と位相)

それでは、Lena画像でフーリエ変換の往復を試してみましょう。つまり、順変換を実行し、すぐに逆変換を適用して元の画像に戻します。次に、結果を比較して、生成された品質レベルを確認します。

  time magick lena.png -fft -ift lena_roundtrip.png


echo -n "RMSE = "
magick compare -metric RMSE lena.png lena_roundtrip.png null:
echo -n "PAE = "
magick compare -metric PAE lena.png lena_roundtrip.png null:
[IM Output] ==> [IM Output]
[IM Text]
上記の「compare」プログラムは、2つの画像がどれだけ異なるかを示す尺度を返します。この場合、一般的な違いは約0.22%と非常に小さいことがわかります。少なくとも1ピクセルのピーク値の差(「PAE」、ピーク絶対誤差)は約1%です。HDRIバージョンのImageMagickを使用することで、これを改善できます。(以下のHDRIを使用したFFTを参照)。上記の往復で生成されたFFT画像を詳しく見てみましょう。

  magick lena.png -fft    +depth +adjoin lena_fft_%d.png
[IM Output]
オリジナル
==> [IM Output]
振幅
[IM Output]
位相
John M. Brayerがフーリエ変換について述べたように... *一般的に位相画像は表示しません。なぜなら、それらを見たほとんどの人は、その後すぐに幻覚剤に屈したり、チベットの僧院に行き着いたりするからです。* 「-fft」演算子は2つの画像を生成することに注意してください。最初の画像は「振幅」成分(ほとんど黒で、中央に単色のドットがあります)で、2番目のほぼランダムに見える画像は「位相」成分を含んでいます。PNG画像はファイルごとに1つの画像しか保存できないため、IMはこれを処理するため、「+adjoin」または出力ファイル名の「%d」は実際には必要ありませんでした。ただし、上記にオプションを含めて完全を期し、1つの画像ファイルではなく2つの別々の画像ファイルを生成していることを明確にしています。詳細については、複数画像シーケンスの書き込みを参照してください。2つの画像が生成されると、振幅画像(最初のゼロ番目の画像)は「lena_fft_0.png」に、位相画像(2番目の画像)は「lena_fft_1.png」に保存されます。
FFT画像の保存による歪みの可能性を防ぐために、画像をディスクにまったく保存せず、画像を処理している間メモリに保持することをお勧めします。

保存する必要がある場合は、画像を最高の品質(ビット深度)で保存するために、Magickファイル形式「MIFF」を使用することをお勧めします。この形式では、1つのファイルに複数の画像を保存することもできます。スクリプト作業の場合は、詳細な「TXT」列挙ピクセル形式を使用することもできます。

JPEG」、「GIF」画像形式を使用して保存しないでください。

これらの画像をWebブラウザなどの実際の表示用にファイルに保存する必要がある場合は、これらの例で行うように、「+depth」を内部デフォルトにリセットした画像形式「PNG」を使用します。ただし、ファイルごとに1つの画像しか保存できません。

TIFF」ファイル形式も使用できますが、Webブラウザではあまり受け入れられませんが、ファイルごとに複数の画像を許可します。

中間画像を単一ファイルに保存する最良の方法は、「MIFF」ファイル形式を使用することです...

  magick lena.png -fft  +depth lena_fft.miff
または、「-write」を使用して、完全に separate filenames に保存することもできます(画像の書き込みを参照)...

  magick lena.png -fft  +depth \
          \( -clone 0 -write lena_magnitude.png +delete \) \
          \( -clone 1 -write lena_phase.png +delete \) \
          null:
上記では、特別な「NULL:」画像形式を使用して、さらに処理するためにメモリに保存されている2つの画像をジャンクしました。最後に、2つの画像を再び読み込み、通常の「空間」画像に戻します...

  magick lena_magnitude.png lena_phase.png -ift lena_restored.png
[IM Output] [IM Output] ==> [IM Output]
FFTプロセスによって生成された両方の画像は、変更に対して非常に敏感であり、小さな変更でも結果が大きく歪む可能性があります。そのため、これらの値を歪める可能性のある画像形式で保存しないことが重要です。画像再構成に使用する場合は、画像を周波数領域から復元する際に両方の画像が必要になることを覚えておくことが重要です。そのため、画像再構成に使用する予定がある場合は、一方の画像を保存してもう一方をジャンクすることはお勧めできません。

強度または位相のみの画像

最後に、振幅成分のみ、または位相成分のみから画像を再構築してみましょう。

  magick lena_fft_0.png  -size 128x128 xc:'gray(50%)' \
                                                  -ift lena_magitude_only.png

  magick -size 128x128 xc:gray1  lena_fft_1.png  -ift lena_phase_only.png
[IM Output]
振幅のみ
[IM Output]
位相のみ
これからわかるように、画像の位置情報のほとんどは位相画像に含まれており、振幅は色の情報の多くを保持しています。情報には重複があるため、これは正確ではありませんが、一般的には当てはまります。「振幅のみ」の画像は、常に白いコーナーを持ちます。これは、一定の50%位相画像が使用されているためです。ランダム化された位相画像を使用することで、これらの白いパッチを削除できます。ただし、中央ピクセルの位相が完全な50%グレイであることを確認してください。そうでない場合、画像全体が暗くなります。「位相のみ」の画像は、変換に一定の1%グレイ(ほぼ純粋な黒)の振幅画像を使用しました。この一定の振幅であっても、特にエッジに沿って非常に強いピクセルのパッチが生成されます。元の画像を再構築するには、両方の画像が必要であることを覚えておく必要があります。

周波数スペクトル画像

振幅画像(最初の画像またはゼロ番目の画像)はほとんど完全に黒く見えることに気付いたでしょう。実際にはそうではありませんが、私たちの目にはすべての値が非常に小さいです。このような画像は実際にはあまり興味深いものではないため、「周波数スペクトル」画像を作成するためにログ変換で結果を向上させましょう。これは、正規化された「振幅」画像に強力な評価ログ変換を適用することによって行われます。

  magick lena_fft_0.png -auto-level -evaluate log 10000 \
          lena_spectrum.png
[IM Output] ==> [IM Output]
これで、振幅画像のスペクトルバージョンの詳細を確認できます。スペクトル画像に特定の色が表示される場合がありますが、一般的にそのような色はスペクトル画像では重要ではありません。はるかに重要なのは、各周波数の全体的な強度とそれらが生成するパターンです。そのため、拡張後にスペクトル画像をグレースケールにすることもできます。使用する必要があるログ拡張の量は画像によって異なるため、画像の周波数スペクトルのパターンがはっきりと見えるようになるまで調整する必要があります。
あるいは、次の小さなシェルスクリプトを使用して、特定の振幅画像に使用する*ログスケーリング係数*を計算できます。

  scale=`magick lena_fft_0.png -auto-level \
          -format "%[fx:exp(log(mean)/log(0.5))]" info:`
  magick lena_fft_0.png -auto-level \
          -evaluate log $scale    lena_spectrum_auto.png
[IM Output]
ただし、スペクトル画像は、明るすぎる画像が生成されるため、逆「-ift」変換には使用できないことに注意してください。

  magick lena_spectrum.png lena_fft_1.png -ift lena_roundtrip_fail.png
基本的には、「振幅」画像を拡張したため、結果の画像も同じ方法で拡張され、示されているようにひどく「クリップされた」結果が生成されます。
[IM Output]

HDRI FFT画像

フーリエ変換の結果を画像表現にマッピングしたとき、浮動小数点「複素数」の値を整数画像値にスケーリングおよび変換しました。これにより、当然のことながら、特に小さな低周波数の振幅で丸め誤差やその他の「量子」効果が発生しました。画像処理で精度が重要な場合は、ビット品質(Q32またはQ64ビットバージョンのImageMagickなど)を使用するか、値が浮動小数点数として保存されるようにHDRIバージョンのImageMagickを使用する必要があります。フーリエ変換の振幅と位相表現でHDRIバージョンのIMを使用する場合、振幅成分は依然としてすべて正の値になるため、上記のように使用できますが、はるかに正確です。ただし、位相成分は、前述のように、バイアスされ、スケーリングされます。つまり、HDRIの振幅と位相の表現はまったく同じですが、はるかに正確です。
たとえば、ここではHDRIバージョンのImageMagickを使用して、画像の別の「往復」変換を生成します。

  # HDRI version of IM used
  time magick lena.png -fft -ift lena_roundtrip_hdri.png


echo -n "RMSE = "
magick compare -metric RMSE lena.png lena_roundtrip_hdri.png null:
echo -n "PAE = "
magick compare -metric PAE lena.png lena_roundtrip_hdri.png null:
[IM Output]
[IM Text]
上記の 결과を以前の非HDRI比較と比較すると...
[IM Text]
HDRIバージョンのIMは、以前とほぼ同じ速度で(速度はコンピューターによって異なる場合があります)、はるかに正確な結果を生成したことがわかります。ただし、通常のQ16 IMよりもはるかに多くのメモリが必要になります(コンパイル時品質を参照)。ただし、このような画像は、画像のFFTの周波数成分をより正確に表していますが、負の値と小数値を含む場合があり、浮動小数点値を処理できる特別なHDRI対応ファイル形式を使用してのみ保存できます。
浮動小数点互換のファイル形式には、「MIFF」、「TIFF」、「PFM」、およびHDRI固有の「EXR」ファイル形式が含まれます。ただし、動作させるには「-define quantum:format=floating-point」を設定する必要がある場合があります。
画像のFFTを処理する後の例では、良好な結果を得るためにそのような精度が必要になります。高速フーリエ変換を使用するにつれて、HDRIバージョンのImageMagickが必要になります。

実数部・虚数部としてのFFT

これまでは、フーリエ変換された画像の「強度」と「位相」表現のみを見てきました。しかし、HDRI版のIMをコンパイルしている場合は、浮動小数点の「実数」と「虚数」成分を使用して画像を処理することもできます。これは、オプション "+fft" と "+ift" のプラスバージョンを使用することで行います。たとえば、ここではHDRI版のIMを使用して、画像の「ラウンドトリップ」FFTを実行しましたが、今回は実数/虚数画像を生成しています。

  # HDRI version of IM used
  time magick lena.png   +fft +ift   lena_roundtrip_ri.png


echo -n "RMSE = "
magick compare -metric RMSE lena.png lena_roundtrip_ri.png null:
echo -n "PAE = "
magick compare -metric PAE lena.png lena_roundtrip_ri.png null:
[IM Output]
[IM Text]
プラス形式を使用して実数/虚数FFT画像を生成する場合は、HDRIバージョンを使用する必要があります。使用しない場合、値の約半分がゼロになり、画像が「汚れた」ように見えます。例えば...

  # non-HDRI Q16 version of IM used  -- THIS IS BAD
  magick lena.png   +fft +ift   lena_roundtrip_ri_bad.png
[IM Output]
覚えておくべきもう1つのことは、生成するFFT画像の形式は、FFT画像に適用するすべての画像処理操作にも影響を与えるということです。これらは非常に異なる画像であるため、異なる数学的演算を使用して、非常に異なる方法で処理する必要があります。また、以前と同様に、最終的な画像を復元するには、実数成分画像と虚数成分画像の両方が必要です。たとえば、コンポーネントの1つを「黒」の画像に置き換えると、次のようになります。

  # HDRI version of IM used
  magick lena.png +fft -delete 1 \
          -size 128x128 xc:black +ift lena_real_only.png
  magick lena.png +fft -delete 0 \
          -size 128x128 xc:black +ift lena_imaginary_only.png
[IM Output]
実数のみ
[IM Output]
虚数のみ
これを見ると、実数/虚数FFT画像の両方に、元の画像に関する重要な情報がほぼ均等に含まれていることがわかります。2つの間の最大の違いは、特別なDCまたは「平均色」には虚数成分がなく、強度画像にのみ存在することです。両方の画像に見られる対角線のミラー(実際には180度回転)効果は、他のコンポーネントに含まれる「符号」情報の損失によって引き起こされます。他のコンポーネントがない場合、波は180度位相がずれていると考えられ、この奇妙な外観が発生します。この情報損失は、2種類の画像間で等しくなります。

フーリエ変換の特性

一定画像のFFT

これらの特性のいくつかを実証してみましょう。まず、一定の色画像を取得し、その強度を取得します。

  magick -size 128x128 xc:gold constant.png
  magick constant.png -fft +delete constant_magnitude.png
[IM Output] ==> [IM Output]
この場合の強度画像は、画像のまさに中心、ピクセル位置 width/2、height/2 にある単一の色のピクセルを除いて、実際には純粋な黒であることに注意してください。このピクセルは、画像のゼロ周波数またはDC(「直流」)値であり、正弦波を表さない唯一のピクセルです。言い換えれば、この値はFFT定数成分にすぎません!
この単一のピクセルをより明確に見るために、画像のその領域も拡大してみましょう...

  magick constant_magnitude.png -gravity center -extent 5x5 \
           -scale 2000% constant_dc_zoom.gif
[IM Output]
DCポイントの色は元の画像と同じであることに注意してください。実際、見ているものが3つの値であることを覚えておくことをお勧めします。つまり、生成される画像は、実際には3つの別々の高速フーリエ変換です。3つの赤、緑、青の画像チャネルごとにFFTがあります。FFT自体は色については実際には何も知らず、色の値または「グレースケール」のみを知っています。実際、FFT変換は、実際には...気にしないので、ほぼすべてのカラースペースに適用できます!フーリエ変換にとって、画像は値の配列にすぎません、それだけです。
DC値の「位相」は重要ではありませんが、常に「ゼロ」角度(位相カラー値は50%グレー)である必要があります。50%グレーに設定されていない場合、DC値には「非現実的な」成分が含まれ、その値は指定された角度によって変調されます。

DCカラーの影響

より典型的な非定数画像では、DC値は画像の平均色です。画像を完全にぼかし、平均化、または単一のピクセルまたは色に縮小した場合に一般的に得られる色です。たとえば、「レナ」画像のFFTからDCピクセルを抽出してみましょう。


magick lena.png -fft +delete lena_magnitude.png magick lena_magnitude.png -gravity center -extent 1x1 \ -scale 60x60 lena_dc_zoom.gif
[IM Output] ==> [IM Output] ==> [IM Output]
ご覧のとおり、画像の平均色は一種の「濃いピンク」色です。この特別なピクセルについて考える別の方法は、それが中心の「バイアス」レベルを表しており、他のすべての正弦波が画像の色を変更することです。
たとえば、その「濃いピンク」のDCピクセルを、「トマト」などのよりオレンジ色の色に置き換えてみましょう...

  magick lena.png -fft \
          \( -clone 0  -draw "fill tomato  color 64,64 point" \) \
          -swap 0 +delete -ift lena_dc_replace.png
[IM Output]
実際に起こっていることは、FFT画像のDC値を変更することにより、画像全体を同じ方法で変更していることです。実際、DC値の変更(差)は、結果の画像の各ピクセルに加算(または減算)されます。これは、元の画像の各ピクセルに実際に定数を追加しているかのようです。そのため、再構築された画像の最終的なピクセルカラーは、最大(白)または最小(黒)の制限によってクリップされる可能性もあります。そのため、これは画像の色合いを変更するための推奨される方法ではありません。これは、画像全体のすべてのピクセルを変更するよりも適用が簡単ですが、FFTラウンドトリップにより、全体としてはるかに遅い色合い変更 teknikになります。

正弦波画像のスペクトル

次に、画像全体に4サイクルの単一の正弦(または余弦)波画像からのスペクトルを見てみましょう。

  magick -size 128x129 gradient: -chop 0x1 -rotate 90 -evaluate sine 4 \
          sine4.png
  magick sine4.png -fft +delete \
          -auto-level -evaluate log 100  sine4_spectrum.png
[IM Output] ==> [IM Output]
上記のグラデーション画像の異常な作成は、結果の正弦波画像が画像全体に完全にタイル状になるようにするために必要です。

通常の "gradient:" 画像は完全にタイル状にならないため、それから生成された正弦波もタイル状になりません。このような不完全なタイルのFFT変換は、フーリエ変換スペクトルに単一の「ドット」ではなく、不要な高調波の配列をもたらします。

この問題の詳細については、完全なグラデーションの生成を参照してください。

上記のスペクトル画像(拡張強度画像)では、3つのドットがあることがわかります。中央のドットは、以前と同様に平均DC値です。他の2つのドットは、フーリエ演算子が画像で見つけた完全な正弦波を表しています。画像の幅全体の周波数は正確に4サイクルであるため、結果として2つの周波数ピクセルは中心DC値から正確に4ピクセル離れています。しかし、なぜ2つのピクセルなのでしょうか?それは、単一の正弦波を2つの完全に異なる方法で記述できるためです(1つは負の方向と位相)。どちらの説明も数学的に正しいものであり、フーリエ変換はそれらを区別しません。これを16サイクルの正弦波で繰り返すと、再び3つのドットがあることがわかりますが、ドットはさらに離れています。この場合、サイドドットは中央ドットの左右に16ピクセル離れています。

  magick -size 128x129 gradient: -chop 0x1 -rotate 90 -evaluate sine 16 \
          -write sine16.png -fft -delete 1 \
          -auto-level -evaluate log 100 sine16_spectrum.png
[IM Output] ==> [IM Output]
これから、完全な正弦波は、適切な位置にある2つのドットで表されることがわかります。この位置が中心DC値からどれだけ離れているかが、正弦波の周波数を決定します。波長が短いほど周波数が高くなるため、ドットはDC値から遠くなります。実際、画像のサイズを周波数(ドットの中心からの距離)で割ると、波の波長(ピーク間の距離)が得られます。上記の例では、128ピクセルを16サイクルで割ると、各「バンド」の間に8ピクセルの波長が得られます。これは、FFT変換の最も重要な特徴の1つです。元の画像の小さな特徴のパターンには、小さな波長、したがって大きな周波数が必要です。その結果、周波数領域で大規模な効果が発生します。同様に、大きな特徴は小さな周波数を使用するため、特に中心に向かって小さなスケールのパターンを生成します。フーリエ変換では...
小は大になり、大は小になります。
これは、フーリエ変換を扱う際に覚えておくべき最も重要な側面の1つです。これは、画像の全体的な大きな側面を維持しながら、ノイズ(小さな特徴)を画像から削除するための鍵となるためです。
元の強度(対数スペクトルではない)をプロットすることにより、これら3つの「周波数」を詳しく見てみましょう。

  magick sine16.png -fft -delete 1  miff:- |\
     im_profile - sine16_magnitude_pf.png
[IM Output]
DC値(画像の平均またはバイアス)の値は1/2であり、これは予想どおりです(画像の平均値は完全な50%グレーです)。しかし、フーリエ変換で見つかった2つの16サイクルの正弦波の実際の強度は、最大値のわずか1/4です。元の正弦波の強度は実際には1/2ですが、フーリエ変換はその強度を2つに分割し、結果を両方のプロットされた周波数波に共有するため、2つのコンポーネントのそれぞれは1/4の強度しかありません。つまり、フーリエ変換の通常の [IM Output]部分です。FFT画像におけるこの正と負の周波数の二重性は、すべてのFFT画像スペクトル(左側に繰り返されるレナスペクトルなど)が常に中心に関して対称である理由を説明しています。画像の片側にあるすべてのドットについて、常に画像の中心を中心に回転ミラーリングされた同様の「ドット」が得られます。FFT画像ペアの「位相」コンポーネントでも同じことが起こりますが、値も180度シフト(負の位相)します。つまり、各画像の半分は実際には他の半分の複製ですが、元の画像を再作成するには両方の画像が必要です。言い換えれば、2つの画像にはまだまったく同じ量の 정보が含まれており、半分は一方の画像に、半分はもう一方の画像にあります。それらが一緒になって全体を生成します。
生成中、FFTアルゴリズムは画像の左半分のみを生成します。残りの半分は、生成されたデータの回転と複製によって生成されます。

周波数領域画像を空間領域画像に戻す場合、アルゴリズムは再び画像の左半分のみを参照します。右半分は単なる複製であるため、完全に無視されます。

そのため、(後の例で)FFT強度画像を「ノッチフィルター」する場合、強度画像の左側のみをフィルター処理する必要があります。右半分を無視することで、作業を節約できます。ただし、わかりやすくするために、両方の半分を「ノッチ」します。

FFT画像の直接生成

それでは、上記の情報を使用して、正弦波の画像を実際に生成してみましょう。必要なのは、黒と50%グレーの画像ペアを作成し、適切な強度と位相で「ドット」を追加することだけです。例えば...

  magick -size 128x128  xc:black \
          -draw 'fill gray(50%)  color 64,64 point' \
          -draw 'fill gray(50%)  color 50,68 point' \
          -draw 'fill gray(25%)  color 78,60 point' \
          generated_magnitude.png
  magick generated_magnitude.png \
          -auto-level -evaluate log 3  generated_spectrum.png
  magick -size 128x128  xc:gray50  generated_phase.png
  magick generated_magnitude.png generated_phase.png \
          -ift  generated_wave.png
[IM Output] [IM Output] ==> [IM Output]
そして、完全な角度のついた(そしてタイル状の)正弦波が現れます。もちろん、特定の周波数でのみ完全な正弦波を生成でき、正方形の画像でのみタイル状になります(後でサイズ変更しない限り)。残念ながら、すべての周波数は水平方向または垂直方向に2の累乗になり、それがこの teknikの主な制限となります。
実際には、IFT変換は画像の右半分を完全に無視するため、正弦波を生成するには最初の(左端の)「gray25」ドットのみが必要でした。これは単に左半分の回転ミラーである必要があります。
DC値の位相は、「ゼロ角度」(50%グレーの色)である必要があります。これが当てはまることを確認しないと、DCカラー値はゼロ以外の位相によって変調され、より暗い、おそらく「クリップされた」画像が生成されます。
位相内の他のピクセルは任意のグレーレベルにすることができ、事実上、画像全体に正弦波を「ロール」させます。繰り返しますが、実際に重要なのは左端のドットの位相だけです。右側は完全に無視されます。中央のDC位相ピクセルが50%グレーのままになるようにしてください。

今後:FFTを使用したパーリンノイズジェネレーター

垂直線のスペクトル

細い線と太い線のFFTスペクトルを表示する 小さな特徴が画像のFFTでどのように「大きく」なり、大きな特徴がどのように「小さく」なるかを示します。単一の調波を持つ「線」と見なすことができる正弦波にそれをリンクします。 線を回転させる

長方形パターン画像のスペクトル

次に、黒い背景の中に幅8、高さ16の白い長方形のスペクトルを見てみましょう。

  magick -size 8x16 xc:white -gravity center \
          -gravity center -background black -extent 128x128 rectangle.png
  magick rectangle.png -fft +delete \
          -auto-level -evaluate log 100 rect_spectrum.png
[IM Output] ==> [IM Output]
ご覧のとおり、結果の画像には非常に特殊なパターンがあり、多くの高調波周波数が含まれています。また、長方形が90度回転しているように見えることもわかります。それは正しくありません。あなたが見ているのは、私たちが前に述べた同じルールです。大きな特徴は小さく、小さな特徴は大きくなります。そのため、長方形の小さい方の寸法が大きく、大きい方の寸法が小さくなりました。それでは、長方形を45度回転させてみましょう。スペクトルも同じ方向に45度回転していることがわかります。

  magick rectangle.png -rotate 45 -gravity center -extent 128x128 \
          -write rect_rot45.png -fft -delete 1 \
          -auto-level -evaluate log 100 rect_rot45_spectrum.png
[IM Output] ==> [IM Output]
ご覧のとおり、周波数領域でも同じ回転が見られます。つまり、回転したオブジェクトの効果はそのフーリエ変換でも回転します。しかし、ここで長方形を移動すると...

  magick rectangle.png -rotate 45  -geometry +30+20 -extent 128x128 \
          -write rect_rot45off.png -fft -delete 1 \
          -auto-level -evaluate log 100 rect_rot45off_spectrum.png
[IM Output] ==> [IM Output]
周波数パターンは移動しませんでした。これは、すべての位置情報が位相画像に含まれているためです。周波数パターン(マグニチュードまたはそのスペクトル)は、移動したために変化しません。この位置の分離は、フーリエ変換を非常に重要にする重要な機能の1つです。フーリエスペクトルパターンを生成したオブジェクトの位置に関係なく、大きな画像内で特定の画像パターンを検索できます。

フラットな円形パターン画像のスペクトル

次に、白い平らな円形パターンを持つ画像のスペクトルを見てみましょう。1つは直径12(半径6)、もう1つは直径24(半径12)です。

  magick -size 128x128 xc:black -fill white  \
          -draw "circle 64,64 64,70" -write circle6.png -fft -delete 1 \
          -auto-level -evaluate log 100 circle6_spectrum.png

  magick -size 128x128 xc:black -fill white  \
          -draw "circle 64,64 64,76" -write circle12.png -fft -delete 1 \
          -auto-level -evaluate log 100 circle12_spectrum.png
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
最初の画像は、上記のjincの例で生成したものと非常によく似ていることに注意してください。ただし、少し壊れています。これらのアーティファクトは、円のサイズが小さいため発生します。デジタルで表現されているため、周囲は完全な円形ではありません。ここでも、小さな詳細は変換された周波数空間で大きくなることがわかります。大きい円の変換は、その周囲が真円に近い近似であるため、より優れています。したがって、実際には、平らな円形の形状の変換はjinc関数であり、直径の小さい円を含む画像は、より広がり、より広い変換フィーチャを生成すると結論付けます。フーリエ変換の数学的特性によると、中心からスペクトルの最初の暗いリングの中央までの距離は1.22 * N / dになります。円の直径がd = 12の場合、距離は1.22 * 128/12 = 13になります。同様に、円の直径がd = 24の場合、距離は1.22 * 128/24 = 6.5になります。

ガウスパターン画像のスペクトル

次に、それぞれシグマが8と16の白いガウス円形パターンを持つ2つの画像のスペクトルを見てみましょう。

  magick -size 128x128 xc:black -fill white \
          -draw "point 64,64" -gaussian-blur 0x8 -auto-level \
          -write gaus8.png -fft -delete 1 \
          -auto-level -evaluate log 1000 gaus8_spectrum.png

  im_profile -s gaus8.png gaus8_pf.gif
  im_profile -s gaus8_spectrum.png gaus8_spectrum_pf.gif
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]

  magick -size 128x128 xc:black -fill white \
          -draw "point 64,64" -gaussian-blur 0x16 -auto-level \
          -write gaus16.png -fft -delete 1 \
          -auto-level -evaluate log 1000 gaus16_spectrum.png

  im_profile -s gaus16.png gaus16_pf.gif
  im_profile -s gaus16_spectrum.png gaus16_spectrum_pf.gif
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
パターンの長方形配列によって生成されたノイズ以外に、結果は、ガウスパターンがほぼ同一のガウス周波数パターンを生成したことです。さらに重要なのは、そのパターンが外観が非常にきれいだったことです。もちろん、同じルールに従って、サイズの違いがあります。大きいものは小さくなり、小さいものは大きくなります。数学的特性から、スペクトルのシグマはN /(2 *シグマ)になります。ここで、シグマは元の画像からのものです。したがって、サイズN = 128、シグマ= 8の画像の場合、スペクトルのシグマは128/16 = 8になります。同様に、画像のシグマが16の場合、スペクトルのシグマは128/32 = 4になります。これは「大きいものは小さくなり、逆もまた同様」というルールの数学的関係であり、知っておくと便利です。

グリッドパターン画像のスペクトル

次に、16x8ピクセル間隔のグリッド線のセットのみを含む画像を変換してみましょう。

  magick -size 16x8 xc:white -fill black \
          -draw "line 0,0 15,0" -draw "line 0,0 0,7" \
          -write mpr:tile +delete \
          -size 128x128 tile:mpr:tile \
          -write grid16x8.png -fft -delete 1 \
          -auto-level -evaluate log 100000 grid16x8_spectrum.png
[IM Output] ==> [IM Output]
結果のスペクトルは、間隔が狭いグリッド線が遠くにあるドットを生成し、逆もまた同様のドットの配列にすぎません。上記の特性によると、グリッド線の間隔は16x8ピクセルであるため、ドットの間隔はN / a = 128/16 = 8およびM / b = 128/8 = 16である必要があります。これは、この画像で測定されたとおりです。このパターンは、フーリエ変換と画像内の規則的なタイリングパターンの関係を知る上で特に重要です。このようなタイリングパターンは、フーリエ変換の中心から離れた場所に非常に強い非中心グリッドパターンを生成します。ここでの重要な点は、形状情報は中心にありますが、タイリング情報はフーリエ変換の中心から離れたグリッドのような配列にあるということです。

スペクトル情報の詳細

スペクトル画像とその特性について詳しく知りたい場合は、いくつかのリンクを以下に示します。

実践的なアプリケーション

さて、基本を説明したので、フーリエ変換を使用する実際的なアプリケーションは何でしょうか?実行できることのいくつかは次のとおりです。1)画像のコントラストを増減する、2)ぼかし、3)シャープニング、4)エッジ検出、5)ノイズ除去。

画像のコントラストの変更 - 係数ルーティング

画像のコントラストを調整するには、順フーリエ変換を実行し、マグニチュード画像をべき乗し、逆フーリエ変換で位相とともに使用します。コントラストを上げるには、1よりわずかに小さい指数を使用し、コントラストを下げるには、1よりわずかに大きい指数を使用します。それでは、まず指数0.9を使用してLena画像のコントラストを上げ、次に指数1.1を使用してコントラストを下げてみましょう。

  magick lena.png -fft \
          \( -clone 0 -evaluate pow 0.9 \) -delete 0 \
          +swap -ift lena_plus_contrast.png

  magick lena.png -fft \
          \( -clone 0 -evaluate pow 1.1 \) -delete 0 \
          +swap -ift lena_minus_contrast.png
[IM Output] ==> [IM Output]
[IM Output] ==> [IM Output]
ただし、これを元の画像に対して行うと、元の画像に対して行うのと同じ効果があります。つまり、マグニチュードのグローバルな変更は、元の画像のグローバルな変更を行った場合と同じ効果があります。

画像のぼかし - ローパスフィルタリング

フーリエ変換の最も重要な特性の1つは、空間領域の畳み込みが周波数領域の単純な乗算と同等であることです。空間領域では、-convoleオプションを使用して、小さく、正方形の、単純な畳み込みフィルター(カーネル)を使用して画像をぼかします。これはローパスフィルターと呼ばれます。最も単純なフィルターは、均等に重み付けされた正方形の配列です。つまり、すべての値は1であり、畳み込みを適用する前に合計で割ることによって正規化されます。これは、ローカルまたは近傍平均に相当します。別のローパスフィルターは、-gaussian-blurまたは-blurのいずれかによって提供される、ガウス重み付けの円形フィルターです。周波数領域では、あるタイプのローパスぼかしフィルターは、黒で囲まれた一定強度の白い円にすぎません。これは、空間領域の円形平均畳み込みフィルターに似ています。ただし、空間領域の畳み込みは周波数領域の乗算と同等であるため、順フーリエ変換を実行し、フィルターにマグニチュード画像を掛けて、最後に逆フーリエ変換を実行するだけで済みます。小さな畳み込みフィルターは、周波数領域の大きな円に対応することに注意してください。乗算は、-compose乗算設定を使用して-compositeを介して実行されます。それでは、直径40(半径20)と直径28(半径14)の2つのサイズの円形フィルターでこれを試してみましょう。

  magick -size 128x128 xc:black -fill white \
          -draw "circle 64,64 44,64" circle_r20.png
  magick lena.png -fft \
       \( -clone 0 circle_r20.png -compose multiply -composite \) \
       \( +clone -evaluate log 10000 -write lena_blur_r20_spec.png +delete \) \
       -swap 0 +delete -ift lena_blur_r20.png

  magick -size 128x128 xc:black -fill white \
          -draw "circle 64,64 50,64" circle_r14.png
  magick lena.png -fft \
       \( -clone 0 circle_r14.png -compose multiply -composite \) \
       \( +clone -evaluate log 10000 -write lena_blur_r14_spec.png +delete \) \
       -swap 0 +delete -ift lena_blur_r14.png
[IM Output] ==> [IM Output] x [IM Output] ==> [IM Output] ==> [IM Output]
[IM Output] ==> [IM Output] ==> [IM Output]
そのため、直径の小さいフィルターを使用した画像の方がぼかしが大きくなることがわかります。また、結果の画像のエッジ付近に「リンギング」または「リップル」効果があることにも注意してください。これは、前述のとおり、円のフーリエ変換がjinc関数であり、中心から外側に進むにつれて振動が減少するためです。ただし、ここでは、前述のように、jinc関数と振動は周波数領域ではなく空間領域にあります。では、これについてどうすればよいでしょうか?最も簡単なことは、さまざまな窓関数を使用して円のエッジをテーパリングすることです。あるいは、定義上すでにテーパリングされているガウス形状などのフィルターを使用することもできます。それでは、後者を実行し、2つのガウスぼかし円を使用して、深刻な「リンギング」効果のほとんどを除去しましょう。

  magick circle_r20.png -blur 0x4 -auto-level gaussian_r20.png
  magick lena.png -fft \
       \( -clone 0 gaussian_r20.png -compose multiply -composite \) \
       \( +clone -evaluate log 10000 -write lena_gblur_r20_spec.png +delete \) \
       -swap 0 +delete -ift lena_gblur_r20.png

  magick circle_r14.png -blur 0x4 -auto-level gaussian_r14.png
  magick lena.png -fft \
       \( -clone 0 gaussian_r14.png -compose multiply -composite \) \
       \( +clone -evaluate log 10000 -write lena_gblur_r14_spec.png +delete \) \
       -swap 0 +delete -ift lena_gblur_r14.png
[IM Output] ==> [IM Output] x [IM Output] ==> [IM Output] ==> [IM Output]
[IM Output] ==> [IM Output] ==> [IM Output]
もちろん、これははるかに優れています。理想的なローパスフィルターは、円をまったくぼかすのではなく、実際には_半径_ではなく_シグマ_の適切なガウス曲線を使用することです。もちろん、この例では、ぼかしを実行するためにぼかしを実行することになりました!ただし、FFTマグニチュード画像に乗算されるぼかしパターンは固定されており、実際には事前に生成されたキャッシュから取得できます。また、乗算する画像は元の画像のフルサイズである必要はなく、より小さい画像を使用できます。そのため、上記は大きな画像の場合、および多くの画像を処理する場合に、はるかに高速になる可能性があります。より重要な点は、大きく強力なぼかしの場合、周波数領域の画像が小さく、元の画像のすべてのピクセルに対して多くのピクセルを平均化するのではなく、単一の乗算のみを行うことです。サイズの小さいぼかしの場合は、より直接的な畳み込みぼかしの方が適している場合があります。

画像のエッジ検出 - ハイパスフィルタリング

空間領域では、画像からエッジを抽出するハイパスフィルタは、合計がゼロになるように正と負の重みを持つ畳み込みとして実装されることがよくあります。周波数領域では、物事ははるかに単純です。ここでは、ハイパスフィルタはローパスフィルタの反転バージョンにすぎません。つまり、ローパスフィルタが明るい場所ではハイパスフィルタは暗く、逆もまた同様です。そのため、ImageMagickでは、ローパスフィルタ画像を-negateするだけで済みます。それでは、円画像を使用して、Lena画像にハイパスフィルタを適用してみましょう。そして、純粋なガウス曲線を使用してもう一度適用します。

  magick circle_r14.png -negate circle_r14i.png
  magick lena.png -fft \
       \( -clone 0 circle_r14i.png -compose multiply -composite \) \
       \( +clone -evaluate log 10000 -write lena_edge_r14_spec.png +delete \) \
       -delete 0 +swap -ift -normalize lena_edge_r14.png

  magick -size 128x128 xc: -draw "point 64,64" -blur 0x14 \
          -auto-level   gaussian_s14i.png
  magick lena.png -fft \
       \( -clone 0 gaussian_s14i.png -compose multiply -composite \) \
       \( +clone -evaluate log 10000 -write lena_edge_s14_spec.png +delete \) \
       -delete 0 +swap -ift -normalize lena_edge_s14.png
[IM Output] ==> [IM Output] x [IM Output] ==> [IM Output] ==> [IM Output]
[IM Output] ==> [IM Output] ==> [IM Output]
これら2つの結果を注意深く見ると、単純な円は「リンギング」アーチファクトがあり、それほどシャープではないため、ガウスほど良くないことがわかります。

画像のシャープ化 - ハイブーストフィルタリング

画像をシャープにする最も簡単な方法は、ハイパスフィルタを適用し(正規化ストレッチなしで)、元の画像とブレンドすることです。

  magick lena.png -fft \
       \( -size 128x128 xc: -draw "point 64,64" -blur 0x14 -auto-level \
          -clone 0 -compose multiply -composite \) \
       -delete 0 +swap -ift \
       lena.png -compose blend -set option:compose:args 100x100 -composite \
       lena_sharp14.png
[IM Output] ==> [IM Output]
ここでは、ハイパスフィルタは周波数領域で行われ、結果は空間領域に逆変換され、元の画像とブレンドされて画像のエッジが強調されます。

ノイズ除去 - ノッチフィルタリング

多くのノイズの多い画像には、何らかのパターン化されたノイズが含まれています。この種のノイズは、パターンが少数の点または線のパターンとして現れるため、周波数領域で簡単に除去できます。単純な正弦波は繰り返しパターンであり、スペクトルでは3つの点としてのみ表示されることを思い出してください。このノイズを除去するには、残念ながら、マグニチュード画像内の点または線を手動でマスク(またはノッチ)する必要があります。これを行うには、周波数領域に変換し、スペクトルのグレースケールバージョンを作成し、点または線をマスクし、しきい値処理を行い、バイナリマスク画像をマグニチュード画像と乗算してから、空間領域に逆変換します。斜めに縞模様のディザのようなパターンを含むピエロ画像でこれを試してみましょう。最初に、ピエロ画像を変換して、そのマグニチュード画像と位相画像を作成します。

  magick clown_orig.jpg -fft \
          \( +clone  -write clown_phase.png +delete \) +delete \
          -write clown_magnitude.png  -colorspace gray \
          -auto-level -evaluate log 100000  clown_spectrum.png
[IM Output]
オリジナル
==> [IM Output]
スペクトル
[IM Output]
位相
スペクトルには、各象限に1つずつ、4つの明るい星のような点があることがわかります。これらの異常な点は、除去したい画像のパターンを表しています。画像の中央にある明るい点と線は、DC(平均画像の色)と画像のエッジの影響を表しており、変更しないでください。スペクトル画像を生成するとき、結果の画像を純粋なグレースケール画像になるように強制しました。これは、画像をエディターにロードし、グレー以外の任意の色(赤など)を使用して、それらの4つの星のようなパターンの領域をマスクアウトできるようにするためです。編集が完了したら、編集されていないバージョンとの差分画像を抽出することにより、着色した領域を抽出できます。このように...

  magick clown_spectrum_edited.png clown_spectrum.png \
          -compose difference -composite \
          -threshold 0 -negate clown_spectrum_mask.png
[IM Output] ==> [IM Output]
これで、マスクをマグニチュードと乗算し、元の位相画像と結果を使用して空間領域に逆変換するだけです。比較のために、元の画像を横に表示します。

  magick clown_magnitude.png clown_spectrum_mask.png \
          -compose multiply -composite \
          clown_phase.png -ift clown_filtered.png
[IM Output] ==> [IM Output]
非常に良い結果です。しかし、さらに改善することができます。前の例で見たように、単純な「円」はFFT画像には特に適していないため、マスクを少しぼかしてみましょう...

  magick clown_spectrum_mask.png \
          -blur 0x5 -level 50x100%  clown_mask_blurred.png
[IM Output]
そして、ピエロをフィルタリングします。今回は、FFT画像をメモリ内で再生成します。

  magick clown_orig.jpg -fft \
          \( -clone 0 clown_mask_blurred.png -compose multiply -composite \) \
          -swap 0 +delete -ift clown_filtered_2.png
[IM Output]
驚くべき結果です!そして、そのマスクを「星」の形状によりよく合うように調整することで、さらに改善できる可能性があります。
元の画像と結果の差をとって、ノイズが除去された領域の画像を作成することもできます。

  magick clown_orig.jpg clown_filtered_2.png -compose difference \
          -composite -normalize clown_noise.png
[IM Output]
別の例でこれを試してみましょう。今回は、RoboRealmWebサイトにある「小枝」画像で、水平および垂直の縞模様の不規則なパターンが含まれています。以前と同じように、グレースケールスペクトル画像を抽出します。

  magick twigs.jpg -fft +delete -colorspace gray \
          -auto-level -evaluate log 100000 twigs_spectrum.png
[IM Output] ==> [IM Output]
この場合、画像のノイズは水平方向と垂直方向に配向されているため、これは中心線に沿って太い水平バンドと垂直バンドとして表示されますが、画像の実際の中心には表示されません。今回も、画像エディターを使用してパーツをマスクアウトします。今回は「青」の色を使用します(実際にはどの色を使用してもかまいません)...

  magick twigs_spectrum_edited.png twigs_spectrum.png \
          -compose difference -composite \
          -threshold 0 -negate twigs_spectrum_mask.png
[IM Output] ==> [IM Output]
これで、マスクとFFTマグニチュード画像を再び乗算し、画像を再構築します。

  magick twigs.jpg -fft \
          \( -clone 0 twigs_spectrum_mask.png -compose multiply -composite \) \
          -swap 0 +delete  -ift twigs_filtered.png
[IM Output] ==> [IM Output]
元の画像と結果の差をとって、ノイズが除去された領域の画像を作成することもできます。

  magick twigs.jpg twigs_filtered.png -compose difference -composite \
          -normalize twigs_noise.png
[IM Output]
マスクに少しぼかしを追加すると、結果がさらに向上する可能性があります。練習として、画像から文字列を削除してみてください。ヒントとして、実際の画像の線の効果がFFTで90度回転されることを忘れないでください。これを間違えると、おそらく小枝が代わりに削除されます。

高度なアプリケーション

フーリエ変換を使用する他のより高度なアプリケーションには、1)モーションブラーおよびデフォーカス画像のデコンボリューション(デブラー)、および2)小さな画像が大きな画像内で最もよく一致する場所を見つけるための正規化相互相関があります。FFTの乗算と除算(デコンボリューション)の例は、より正式に定義された画像処理演算子を待機しているため、サブディレクトリに移動されました。