この記事では、画像処理におけるフーリエ変換について解説します。
画像処理におけるフーリエ変換
フーリエ変換は周波数解析ができる便利なデータ変換です。
画像に対しても利用できますが、周波数の考え方が通常の信号とは異なるので注意する必要があります。
- 通常の信号データ
- 周波数=単位時間内にどのくらい振動するか
- 画像データ
- 周波数=単位ピクセル内に画素値がどのくらい変化するか
よって、画像データの周波数は1[px]移動したときの画素値の変化が激しいほど高周波となります。画像処理でのフーリエ変換は「時間領域→周波数領域」ではなく「空間領域→空間周波数領域」となります。
また、画像データは2次元であり、水平方向と垂直方向の2つの空間周波数成分を持っています。
画像データに対する2次元FFTは次の手順で行います。
①画像データの水平方向に1次元FFTを行います。
②画像を転置し、再び水平方向に1次元FFTを行います。
③もう1度画像を転置すれば完成です。
手順①~③で結果的に画像データに対して水平方向と垂直方向に1次元FFTを行うことになります。
ただし、FFTを利用するには画像の縦横の画素数[px]が2の冪乗である必要があります。
画像の振幅スペクトル
振幅スペクトルとは
画像データに対して2次元FFT(手順①~③)を行うと次のような振幅スペクトルが得られます。
※プロ生ちゃんの画像をお借りして入力しました。
この振幅スペクトルは、中心から離れるに従って低周波数成分になるスペクトルで、画像データの周波数分布を表します。
画素値が大きい(白っぽい)ほど、その周波数成分が多く含まれていることになります。
つまり、中心付近に白い画素が集中するほど画像に高周波成分が多く含まれることを意味します。
(逆に、四隅付近に集中すれば低周波数成分が多く含まれる)
このように画像の振幅スペクトルからも(空間)周波数成分の解析ができます。
空間周波数領域の入れ替え
振幅スペクトルを利用する場合、第1象限と第3象限、第2象限と第4象限を入れ替えて利用するのが一般的です。
その際、中心から離れるに従って高周波数成分となるスペクトルへ変換されます。
入れ替えにより、後述する空間周波数フィルタリングを簡単に行うことができるようになります。
■入れ替えた例
空間周波数フィルタリング
空間周波数フィルタリングでは、画像から特定の周波数成分のみを取り出します。
代表的なものは「ローパスフィルタ」「ハイパスフィルタ」「バンドパスフィルタ」です。
- ローパスフィルタ
- 低周波数成分のみを通過させるフィルタ
- 画像のノイズ除去など
- ハイパスフィルタ
- 高周波成分のみを通過させるフィルタ
- 画像の輪郭、特徴点抽出など
- バンドパスフィルタ
- 特定範囲の周波数成分のみを通過させるフィルタ
- 画像のデータ圧縮など(見た目の影響が少ない成分を除去)
空間周波数フィルタの設計例と操作手順
周波数領域の象限を入れ替えることで次のように空間周波数フィルタリングを簡単に行うことができます。
ローパスフィルタ(a)では、中心付近にある低周波数成分のみを通過させます。
一方、ハイパスフィルタ(b)では端の方にある高周波数成分のみを通過させます。
プログラムで実装する場合、カットする領域のスペクトルのみを0にします。
操作手順
空間周波数フィルタリングの基本的な操作手順は次の通りです。
①画像を2次元FFTします。
②周波数領域を入れ替えます。
③各種フィルタリングを行います。(例えばローパスフィルタならカット領域のスペクトルを0にします)
④周波数領域を入れ替えます。(元に戻す)
⑤2次元の逆FFTをします。
⑥フィルタリングされた画像が完成します。
【実行例】FFTとローパスフィルタを利用
実際にFFTとローパスフィルタを利用した例です。
■入力画像(右)とフィルタ処理後の画像(左)
【実装例1】PythonとOpenCVで画像のフーリエ変換
PythonとOpenCVで画像のフーリエ変換を行うプログラムについて以下ページで別途解説しています。
【実装例2】C#で画像のフーリエ変換
C#で画像のフーリエ変換を行うプログラムについて以下ページで別途解説しています。
コメント