【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

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

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

    # 高速フーリエ変換(2次元)
    fimg = np.fft.fft2(gray)
    
    # 周波数領域に変換した画像データを表示
    print(fimg)

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

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

if __name__ == "__main__":
    main()

実行結果

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

入力画像

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入門 サンプル集
【画像処理】画像のフーリエ変換(DFT、FFT)
【Python】画像処理プログラミング入門
【画像処理入門】アルゴリズム&プログラミング

シェア&フォローお願いします!