以下の記事のように、平滑化処理をした後の画像を元画像と比べてみると、肉眼ではほとんどわからないくらいの違いの時があります。
そのような時に、画像をフーリエ変換してみることで高周波成分(ノイズ)がどれだけ取り除けているかがわかります。
一般的な信号解析では、単位時間あたりの振動数を角周波数として扱っていますが、画像の場合は単位ピクセルあたりの画素値(濃淡)の変化を振動としています。
画像の場合これが縦と横2つあるので、二次元フーリエ変換を行なっていくことになります。
目次
高速FFTで空間周波数領域に変換
フーリエ変換の式だけをみると難しそうな気がしますが、numpyがfftメソッドを用意しているのでそれを使うだけです。
from matplotlib import pyplot as plt
import cv2
import numpy as np
def get_fft_img(img,output_name):
fig = plt.figure()
img = cv2.imread(img,0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
fig.savefig(str(output_name)+'.jpg')
解析対象画像は前回と同じ花の画像です。
まずはグレースケール化したもののスペクトラムを見ていきます。
![](https://japbros-poco.main.jp/wp-content/uploads/2022/03/gray_fft.jpg)
次にカーネルサイズ25でガウシアンブラー処理を行なったもののスペクトルを解析します。
![](https://japbros-poco.main.jp/wp-content/uploads/2022/03/k25_fft.jpg)
肉眼での違いはほとんど分かりませんが、周波数としてみてみると少し変わっていますね。
(中心に近いほど低周波成分となります。)
標準偏差を変えてみる
ガウシアンブラーメソッドの引数sigmaXに標準偏差を与えると、平滑化の強度をコントロールできます。
極端に強くしたものを使って効果を比較してみます。
def set_two_imgs(img_1,img_2,output_name):
fig = plt.figure()
img_1 = cv2.imread(img_1,0)
img_2 = cv2.imread(img_2,0)
plt.subplot(121),plt.imshow(img_1, cmap = 'gray')
plt.title('img_gray'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img_2, cmap = 'gray')
plt.title('img(k=25,σ=5)'), plt.xticks([]), plt.yticks([])
fig.savefig(str(output_name)+'.jpg')
if __name__ =='__main__':
set_two_imgs('img_gray','img(k=25,σ=5)','result')
![](https://japbros-poco.main.jp/wp-content/uploads/2022/03/result-1.jpg)
右側の画像のスペクトルを出してみます。
![](https://japbros-poco.main.jp/wp-content/uploads/2022/03/result_fft.jpg)
ガウシアンブラーによる平滑化処理で、高周波成分が取り除けているのが分かります。