【Python/OpenCV】高速フーリエ変換で空間周波数領域に変換

Python版OpenCVとNumPyを用いて、画像データを高速フーリエ変換により(空間)周波数領域に変換する方法をソースコード付きで解説します。

FFTで(空間)周波数領域に変換

NumPyには、2次元配列の高速フーリエ変換をおこなうメソッド「numpy.fft.fft2(img)」があります。
今回はこれらを用いて、OpenCVで読み込んだ画像をFFT(高速フーリエ変換)し、空間周波数領域に変換しました。

書式①

fx =  numpy.fft.fft2(x)

2次元配列xを2次元フーリエ変換します。

書式②

fx2 =  numpy.fft.fftshift(fx)

2次元配列fxの第1象限と第3象限、第2象限と第4象限をそれぞれ入れ替えて、零周波数成分を中心に移動します。(fxが1次元配列の場合は左半分と右半分を入れ替えます)
これを使うことで、元々4隅が低周波成分だったのが、中心が低周波数となり解析がしやすくなります。

ソースコード(Python3+OpenCV3)

サンプルプログラムのソースコードです。

# -*- coding: utf-8 -*-
import numpy as np
import cv2

# 入力画像を読み込み
img = cv2.imread("input2.png")

# グレースケール変換
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

# 高速フーリエ変換(2次元)
fimg = np.fft.fft2(gray)

# 周波数領域に変換した画像データを表示
rint(fimg)

# 零周波数成分を配列の左上から中心に移動
fimg =  np.fft.fftshift(fimg)

# 零周波数成分を中心に移動した結果を表示
print(fimg)

実行結果

サンプルプログラムの実行結果です。

入力画像

4*4の簡単な画像を入力しました。

周波数領域

FFTの結果です。

[[ 988.  +0.j -494.-494.j    0.  +0.j -494.+494.j]
 [   0.  +0.j    0.  +0.j    0.  +0.j    0.  +0.j]
 [-988.  +0.j  494.+494.j    0.  +0.j  494.-494.j]
 [   0.  +0.j    0.  +0.j    0.  +0.j    0.  +0.j]]

零周波数成分を中心に移動

第1象限と第3象限、第2象限と第4象限をそれぞれ入れ替えて、零周波数成分を中心に移動した結果です。

[[   0.  +0.j  494.-494.j -988.  +0.j  494.+494.j]
 [   0.  +0.j    0.  +0.j    0.  +0.j    0.  +0.j]
 [   0.  +0.j -494.+494.j  988.  +0.j -494.-494.j]
 [   0.  +0.j    0.  +0.j    0.  +0.j    0.  +0.j]]

関連ページ

【Python版OpenCV超入門】使い方とサンプルコードを解説
Python版OpenCVで画像処理プログラミングを行う方法を入門者向けにソースコード付きで解説するページです。
【高速フーリエ変換】ナイキスト周波数とサンプリング周波数の違いとエイリアシング
高速フーリエ変換(FFT)におけるナイキスト周波数とサンプリング周波数の違いとエイリアシングについてまとめました。

コメント