この記事では、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】画像処理プログラミング入門
【画像処理入門】アルゴリズム&プログラミング


コメント