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 -size 20x150 gradient: -rotate 90 \ -function sinusoid 3.5,0,.4 wave.gif im_profile -s wave.gif wave_profile.gif |
![[IM Output]](wave.gif)

![[IM Output]](wave_profile.gif)
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]](wave_1_pf.gif)

![[IM Output]](wave_2_pf.gif)

![[IM Output]](wave_3_pf.gif)

![[IM Output]](added_waves_pf.gif)
画像における2次元波
上記は、複数の正弦波で画像の単一行のプロファイルを近似する方法の一例を示しています。 ただし、画像は2次元であるため、「周波数領域」で画像を表すために使用される波も2次元である必要があります。 これは、そのような2次元波の一例です。 波にはいくつかのコンポーネントがあります。 画像例ImageMagickにおけるFFT/IFTの使い方
実装に関する注意事項
ImageMagickは、画像を浮動小数点値(複素数)に変換する必要があるFFTW、離散フーリエ変換ライブラリを使用しており、IMバージョン6.5.4-3で初めて実装されました。 画像に一般的に期待されるように動作させるために、正方形でない画像または奇数次元を持つ画像は、画像の最大幅または高さの正方形になるようにパディングされます(仮想ピクセルを使用)。 「FFT原点」を画像の中心に適切に配置できるように、偶数(2の倍数)の次元を持つように強制されます。 この結果、逆フーリエ変換を適用した後、パディングを削除するために画像を元の寸法にトリミングする必要があります。 フーリエ変換は「複素数」で構成されているため、変換の結果を直接視覚化することはできません。 したがって、複素変換は、2つの形式のいずれかで2つのコンポーネント画像に分割されます。![]() 複素数 実数部/虚数部 |
実数部と虚数部
「複素数」の通常の数学的および数値的表現は、「実数部」(a)と「虚数部」(b)のコンポーネントで構成される浮動小数点値のペアです。 残念ながら、これら2つの数値には負の値が含まれている可能性があるため、表示可能な画像を形成しません。 そのため、この表現は、そのような画像をクリップする通常のImageMagickでは使用できません(結果の効果の以下の例を参照)。 ただし、HDRIバージョンのImageMagickを使用すると、フーリエ変換された画像のこの表現を生成、使用、さらには保存することもできます。 それらは、それ自体では画像として有用または表示可能ではない場合がありますが、それでも多くの数学演算を適用できます。 この表現を生成するには、演算子の「プラス」形式である "+fft
" および "+ift
" を使用します。これについては、以下の実数部・虚数部としてのFFTで詳しく説明します。![]() 複素極座標 強度/位相 |
強度と位相
画像処理において、「複素数」を直接数値表現する方法はあまり有用ではありません。しかし、値を2次元平面にプロットすることで、値を「振幅」(r)と「位相」(θ)成分からなる極座標表現に変換できます。この形式は画像処理、特に振幅成分において非常に役立ちます。振幅成分は、画像を構成するすべての周波数を本質的に指定します。振幅成分は正の値のみを含み、画像値に直接マッピングされます。値の固定範囲はありませんが、DCまたはゼロ周波数の色を除いて、値は一般的に非常に小さくなります。その結果、振幅画像は一般的に非常に暗く(実際には黒く)見えます。視覚的な詳細を引き出すには、通常、振幅をスケーリングし、その強度値にログ変換を適用する必要があります。結果として得られる「ログ変換された」振幅画像は、画像の「スペクトル」として知られています。ただし、逆変換には「スペクトル」画像ではなく、「振幅」画像を使用する必要があることに注意してください。画像の中心「原点」に表示されるDC(「直流」の略)または「ゼロ周波数」の色は、画像全体の平均色値になります。また、入力画像には「虚数」成分が含まれていないため、DC位相値は常にゼロ位相になり、純粋なグレーの色が生成されます。ただし、位相成分の範囲は-πから+πです。これは最初に0から2πの範囲にバイアスされ、次にコンパイル時メモリ品質によって決定される0から*QuantumRange*までの実際の画像値にスケーリングされます。この結果、ゼロ位相は純粋なグレー値(各チャネルに適切な値)を持ち、負の位相は純粋な黒( '0
')値になります。純粋な白( '*QuantumRange*
')はほぼ同じですが、完全に同じではありません。画像の振幅と位相FFT表現は、通常のFFT演算子「+fft
」と「+ift
」を使用して生成されます。これは、最初にFFT画像とその逆変換の生成で検討します。 FFT画像とその逆変換の生成
(振幅と位相)
それでは、Lena画像でフーリエ変換の往復を試してみましょう。つまり、順変換を実行し、すぐに逆変換を適用して元の画像に戻します。次に、結果を比較して、生成された品質レベルを確認します。
|
![[IM Output]](../img_photos/lena.png)

![[IM Output]](lena_roundtrip.png)
![]() |
compare
」プログラムは、2つの画像がどれだけ異なるかを示す尺度を返します。この場合、一般的な違いは約0.22%
と非常に小さいことがわかります。少なくとも1ピクセルのピーク値の差(「PAE
」、ピーク絶対誤差)は約1%
です。HDRIバージョンのImageMagickを使用することで、これを改善できます。(以下のHDRIを使用したFFTを参照)。上記の往復で生成されたFFT画像を詳しく見てみましょう。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つの画像を再び読み込み、通常の「空間」画像に戻します...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 |
![]() 振幅のみ |
![]() 位相のみ |
周波数スペクトル画像
振幅画像(最初の画像またはゼロ番目の画像)はほとんど完全に黒く見えることに気付いたでしょう。実際にはそうではありませんが、私たちの目にはすべての値が非常に小さいです。このような画像は実際にはあまり興味深いものではないため、「周波数スペクトル」画像を作成するためにログ変換で結果を向上させましょう。これは、正規化された「振幅」画像に強力な評価ログ変換を適用することによって行われます。これで、振幅画像のスペクトルバージョンの詳細を確認できます。スペクトル画像に特定の色が表示される場合がありますが、一般的にそのような色はスペクトル画像では重要ではありません。はるかに重要なのは、各周波数の全体的な強度とそれらが生成するパターンです。そのため、拡張後にスペクトル画像をグレースケールにすることもできます。使用する必要があるログ拡張の量は画像によって異なるため、画像の周波数スペクトルのパターンがはっきりと見えるようになるまで調整する必要があります。ただし、スペクトル画像は、明るすぎる画像が生成されるため、逆「-ift 」変換には使用できないことに注意してください。
|
![]() |
HDRI FFT画像
フーリエ変換の結果を画像表現にマッピングしたとき、浮動小数点「複素数」の値を整数画像値にスケーリングおよび変換しました。これにより、当然のことながら、特に小さな低周波数の振幅で丸め誤差やその他の「量子」効果が発生しました。画像処理で精度が重要な場合は、ビット品質(Q32またはQ64ビットバージョンのImageMagickなど)を使用するか、値が浮動小数点数として保存されるようにHDRIバージョンのImageMagickを使用する必要があります。フーリエ変換の振幅と位相表現でHDRIバージョンのIMを使用する場合、振幅成分は依然としてすべて正の値になるため、上記のように使用できますが、はるかに正確です。ただし、位相成分は、前述のように、バイアスされ、スケーリングされます。つまり、HDRIの振幅と位相の表現はまったく同じですが、はるかに正確です。たとえば、ここではHDRIバージョンのImageMagickを使用して、画像の別の「往復」変換を生成します。
|
![]() |
![]() ![]() |
浮動小数点互換のファイル形式には、「MIFF 」、「TIFF 」、「PFM 」、およびHDRI固有の「EXR 」ファイル形式が含まれます。ただし、動作させるには「-define quantum:format=floating-point 」を設定する必要がある場合があります。 |
実数部・虚数部としてのFFT
これまでは、フーリエ変換された画像の「強度」と「位相」表現のみを見てきました。しかし、HDRI版のIMをコンパイルしている場合は、浮動小数点の「実数」と「虚数」成分を使用して画像を処理することもできます。これは、オプション "+fft
" と "+ift
" のプラスバージョンを使用することで行います。たとえば、ここではHDRI版のIMを使用して、画像の「ラウンドトリップ」FFTを実行しましたが、今回は実数/虚数画像を生成しています。
|
![]() |
プラス形式を使用して実数/虚数FFT画像を生成する場合は、HDRIバージョンを使用する必要があります。使用しない場合、値の約半分がゼロになり、画像が「汚れた」ように見えます。例えば...
|
![]() |
|
![]() 実数のみ |
![]() 虚数のみ |
フーリエ変換の特性
一定画像のFFT
これらの特性のいくつかを実証してみましょう。まず、一定の色画像を取得し、その強度を取得します。この場合の強度画像は、画像のまさに中心、ピクセル位置 width/2、height/2 にある単一の色のピクセルを除いて、実際には純粋な黒であることに注意してください。このピクセルは、画像のゼロ周波数またはDC(「直流」)値であり、正弦波を表さない唯一のピクセルです。言い換えれば、この値はFFT定数成分にすぎません!この単一のピクセルをより明確に見るために、画像のその領域も拡大してみましょう...
|
![]() |
![]() ![]() |
DC値の「位相」は重要ではありませんが、常に「ゼロ」角度(位相カラー値は50%グレー)である必要があります。50%グレーに設定されていない場合、DC値には「非現実的な」成分が含まれ、その値は指定された角度によって変調されます。 |
DCカラーの影響
より典型的な非定数画像では、DC値は画像の平均色です。画像を完全にぼかし、平均化、または単一のピクセルまたは色に縮小した場合に一般的に得られる色です。たとえば、「レナ」画像のFFTからDCピクセルを抽出してみましょう。
|
![[IM Output]](../img_photos/lena.png)

![[IM Output]](lena_magnitude.png)

![[IM Output]](lena_dc_zoom.gif)
たとえば、その「濃いピンク」のDCピクセルを、「トマト」などのよりオレンジ色の色に置き換えてみましょう...
|
![]() |
正弦波画像のスペクトル
次に、画像全体に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]](sine4.png)

![[IM Output]](sine4_spectrum.png)
![]() ![]() |
上記のグラデーション画像の異常な作成は、結果の正弦波画像が画像全体に完全にタイル状になるようにするために必要です。 通常の " gradient: " 画像は完全にタイル状にならないため、それから生成された正弦波もタイル状になりません。このような不完全なタイルのFFT変換は、フーリエ変換スペクトルに単一の「ドット」ではなく、不要な高調波の配列をもたらします。この問題の詳細については、完全なグラデーションの生成を参照してください。 |
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]](sine16.png)

![[IM Output]](sine16_spectrum.png)
小は大になり、大は小になります。
これは、フーリエ変換を扱う際に覚えておくべき最も重要な側面の1つです。これは、画像の全体的な大きな側面を維持しながら、ノイズ(小さな特徴)を画像から削除するための鍵となるためです。元の強度(対数スペクトルではない)をプロットすることにより、これら3つの「周波数」を詳しく見てみましょう。
|
![]() |
![[IM Output]](lena_spectrum.png)
![]() ![]() |
生成中、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]](generated_spectrum.png)
![[IM Output]](generated_phase.png)

![[IM Output]](generated_wave.png)
![]() ![]() |
実際には、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]](rectangle.png)

![[IM Output]](rect_spectrum.png)
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]](rect_rot45.png)

![[IM Output]](rect_rot45_spectrum.png)
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]](rect_rot45off.png)

![[IM Output]](rect_rot45off_spectrum.png)
フラットな円形パターン画像のスペクトル
次に、白い平らな円形パターンを持つ画像のスペクトルを見てみましょう。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]](circle6.png)

![[IM Output]](circle6_spectrum.png)
![[IM Output]](circle12.png)

![[IM Output]](circle12_spectrum.png)
ガウスパターン画像のスペクトル
次に、それぞれシグマが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 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
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 |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
グリッドパターン画像のスペクトル
次に、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]](grid16x8.png)

![[IM Output]](grid16x8_spectrum.png)
スペクトル情報の詳細
スペクトル画像とその特性について詳しく知りたい場合は、いくつかのリンクを以下に示します。実践的なアプリケーション
さて、基本を説明したので、フーリエ変換を使用する実際的なアプリケーションは何でしょうか?実行できることのいくつかは次のとおりです。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]](../img_photos/lena.png)

![[IM Output]](lena_plus_contrast.png)
![[IM Output]](../img_photos/lena.png)

![[IM Output]](lena_minus_contrast.png)
画像のぼかし - ローパスフィルタリング
フーリエ変換の最も重要な特性の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 |
![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
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 |
![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
画像のエッジ検出 - ハイパスフィルタリング
空間領域では、画像からエッジを抽出するハイパスフィルタは、合計がゼロになるように正と負の重みを持つ畳み込みとして実装されることがよくあります。周波数領域では、物事ははるかに単純です。ここでは、ハイパスフィルタはローパスフィルタの反転バージョンにすぎません。つまり、ローパスフィルタが明るい場所ではハイパスフィルタは暗く、逆もまた同様です。そのため、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 |
![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
![]() ![]() ![]() ![]() ![]() |
画像のシャープ化 - ハイブーストフィルタリング
画像をシャープにする最も簡単な方法は、ハイパスフィルタを適用し(正規化ストレッチなしで)、元の画像とブレンドすることです。
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]](../img_photos/lena.png)

![[IM Output]](lena_sharp14.png)
ノイズ除去 - ノッチフィルタリング
多くのノイズの多い画像には、何らかのパターン化されたノイズが含まれています。この種のノイズは、パターンが少数の点または線のパターンとして現れるため、周波数領域で簡単に除去できます。単純な正弦波は繰り返しパターンであり、スペクトルでは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 |
![]() オリジナル |
![]() |
![]() スペクトル |
![]() 位相 |
magick clown_spectrum_edited.png clown_spectrum.png \ -compose difference -composite \ -threshold 0 -negate clown_spectrum_mask.png |
![[IM Output]](clown_spectrum_edited.png)

![[IM Output]](../img_photos/clown_spectrum_mask.png)
magick clown_magnitude.png clown_spectrum_mask.png \ -compose multiply -composite \ clown_phase.png -ift clown_filtered.png |
![[IM Output]](clown_orig.jpg)

![[IM Output]](clown_filtered.png)
非常に良い結果です。しかし、さらに改善することができます。前の例で見たように、単純な「円」はFFT画像には特に適していないため、マスクを少しぼかしてみましょう...
|
![]() |
そして、ピエロをフィルタリングします。今回は、FFT画像をメモリ内で再生成します。
|
![]() |
元の画像と結果の差をとって、ノイズが除去された領域の画像を作成することもできます。
|
![]() |
magick twigs.jpg -fft +delete -colorspace gray \ -auto-level -evaluate log 100000 twigs_spectrum.png |
![[IM Output]](twigs.jpg)

![[IM Output]](twigs_spectrum.png)
magick twigs_spectrum_edited.png twigs_spectrum.png \ -compose difference -composite \ -threshold 0 -negate twigs_spectrum_mask.png |
![[IM Output]](twigs_spectrum_edited.png)

![[IM Output]](../img_photos/twigs_spectrum_mask.png)
magick twigs.jpg -fft \ \( -clone 0 twigs_spectrum_mask.png -compose multiply -composite \) \ -swap 0 +delete -ift twigs_filtered.png |
![[IM Output]](twigs.jpg)

![[IM Output]](twigs_filtered.png)