【Python/OpenCV】フーリエ変換+ハイパスフィルタ

この記事では、Python版OpenCVとNumPyを用いてフーリエ変換とハイパスフィルタを実装し、画像から輪郭を取り出す方法をソースコード付きで解説します。

ハイパスフィルタ

ハイパスフィルタとは、その名の通り、信号の高周波数成分のみを通過させます。
画像データの場合は、画素値の変化が大きい輪郭部分やノイズが高周波成分となります。

関連記事
原理の詳細 【画像処理】フーリエ変換(DFT、FFT)
画像のフーリエ変換 【Python/OpenCV】高速フーリエ変換で周波数領域に変換

今回は、Python+OpenCVを用いて画像をハイパスフィルタに通しました。

処理手順
高速フーリエ変換で画像データを空間領域から空間周波数領域に変換します。
零周波数成分を中心に移動します。(空間周波数領域の中心ほど低周波数成分)
ハイパスフィルタで高周波成分のみを取り出します。(空間周波数領域の中心のデータは0に置換)
高速逆フーリエ変換で空間領域に戻します。

ソースコード(Python3+OpenCV3)

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

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

def highpass_filter(src, a = 0.5):
    # 高速フーリエ変換(2次元)
    src = np.fft.fft2(src)
    
    # 画像サイズ
    h, w = src.shape
   
    # 画像の中心座標
    cy, cx =  int(h/2), int(w/2)
    
    # フィルタのサイズ(矩形の高さと幅)
    rh, rw = int(a*cy), int(a*cx)

    # 第1象限と第3象限、第1象限と第4象限を入れ替え
    fsrc =  np.fft.fftshift(src)  

    # 入力画像と同じサイズで値0の配列を生成
    fdst = fsrc.copy()

    # 中心部分だけ0を代入(中心部分以外は元のまま)
    fdst[cy-rh:cy+rh, cx-rw:cx+rw] = 0
    
    # 第1象限と第3象限、第1象限と第4象限を入れ替え(元に戻す)
    fdst =  np.fft.fftshift(fdst)

    # 高速逆フーリエ変換 
    dst = np.fft.ifft2(fdst)
   
    # 実部の値のみを取り出し、符号なし整数型に変換して返す
    return  np.uint8(dst.real)
    

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

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

    # ハイパスフィルタ処理
    himg = highpass_filter(gray, 0.8)

    # 結果をグラフに出力
    cv2.imwrite("output.png", himg)

if __name__ == "__main__":
    main()

実行結果

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

■入力画像(左)と出力画像(右)

おすすめ記事

PythonでOpenCV入門 サンプル集
【Python】画像処理プログラミング入門
【画像処理入門】アルゴリズム&プログラミング

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