完全に実力不足な理系大学生からの成長ブログ

プログラミング能力皆無、でも頑張ります。

OpenCV + NumPy で画像の周波数フィルタ

プログラムが正しく動いていないことを確認しました。
修正まで少々お待ち下さい。2016/07/29

こんにちは、よりです。
今回は画像とフィルターをフーリエ変換し、周波数空間でフィルター処理を行います。

流れ

  1. 元画像をフーリエ変換
  2. フィルターをフーリエ変換
  3. 画素ごとに乗算
  4. 逆変換

大まかにはこんな感じです。
細かい点を補足するとフィルターをフーリエ変換するときの画像サイズですね。
元画像と同じサイズにしてからフーリエ変換します。


今回の入力画像はこちら。
f:id:yori1029:20160705105925j:plain

いつも通りです。

ではコードを見てみましょう。(めっちゃ汚いけど。)

import cv2
import numpy as np

image = cv2.imread("lena.png", 0)
cv2.imshow("in",image)

#画像のフーリエ変換
fimage = np.fft.fft2(image)
"""
outfimage = np.log(np.abs(fimage) + 1)
outfimage = outfimage / np.amax(outfimage) * 255
outfimage = outfimage.astype(np.uint8)
cv2.imshow("fftimage",outfimage)
cv2.imwrite("fftimage.png",outfimage)
"""
#単純平滑化フィルタ
a = np.array([[1/25.0, 1/25.0, 1/25.0, 1/25.0, 1/25.0],
              [1/25.0, 1/25.0, 1/25.0, 1/25.0, 1/25.0],
              [1/25.0, 1/25.0, 1/25.0, 1/25.0, 1/25.0],
              [1/25.0, 1/25.0, 1/25.0, 1/25.0, 1/25.0],
              [1/25.0, 1/25.0, 1/25.0, 1/25.0, 1/25.0]])

#画像サイズを0で初期化した配列を用意
A = np.zeros((512,512)) 

#用意した配列にフィルターをコピー
A[0:5, 0:5] = a[0:5, 0:5]

#フィルターのフーリエ変換
fa = np.fft.fft2(A)
"""
outfa = np.log(np.abs(fa) + 1)
outfa = outfa / np.amax(outfa) * 255
outfa = outfa.astype(np.uint8)
cv2.imshow("fftfa",outfa)
cv2.imwrite("fftfa.png",outfa)
"""
#要素ごとの乗算
outimg = fa * image
"""
foutimg = np.log(np.abs(outimg) + 1)
foutimg = foutimg / np.amax(foutimg) * 255
foutimg = foutimg.astype(np.uint8)
cv2.imshow("aftimg",foutimg)
cv2.imwrite("aftimg.png",foutimg)
"""

#逆変換
fout = np.fft.ifft2(outimg)
out = fout.real + 128l
out = out.astype(np.int8) 
cv2.imshow("out",out)

cv2.waitKey(0)

コメントにしている部分は出力ようなのでスルーしてください。
この処理で周波数空間でのフィルター処理ができます。

5×5の単純平滑化フィルタなのでボケ画像が出力されますね。
f:id:yori1029:20160713011136p:plain

ボケてるのがわかりますよね?


一応周波数空間に変換した時の画像も載せておきます。

まず画像のフーリエ変換
f:id:yori1029:20160713011233p:plain


次にフィルターのフーリエ変換
f:id:yori1029:20160713011259p:plain


最後にこれら二つを要素ごとに乗算したもの(逆変換前)
f:id:yori1029:20160713011336p:plain


他のフィルターも試してみたいですね!
(試さずに終わり)