つれづれなる備忘録

日々の発見をあるがままに綴る

OpenCVの使い方34 ~ 画像のフーリエ変換2

前回紹介した画像のフーリエ変換でNumpyの関数とOpenCVの関数を用いたが、今回は両者の処理時間を比較してみる。

atatat.hatenablog.com

1. フーリエ変換に最適な配列数

画像はサイズが256x256など整っていない画像を読み込む。

道路
道路

画像サイズを調べると484x728となっている。

[rows,cols]=gray.shape[0:2]
[rows,cols]
>[484, 728]

次にFFT処理で最適な画像サイズをcv2.getOptimalIDFTSize()を用いて以下のように求めることができる。

nrows = cv2.getOptimalDFTSize(rows)
ncols = cv2.getOptimalDFTSize(cols)
[nrows,ncols]
>[486, 729]

画像サイズをFFT最適な486x729とするため、元の画像に"0"を付け足す処理を行う。"0"を付け足した画像をnimgとして、画像サイズを確認すると486x729になっている。

right = ncols - cols
bottom = nrows - rows
bordertype = cv2.BORDER_CONSTANT
nimg = cv2.copyMakeBorder(gray,0,bottom,0,right,bordertype, value = 0)

nimg.shape[0:2]
>(486, 729)

2. FFT処理時間の比較

FFT処理時間の比較として、元の画像484x728:gray, 最適画像サイズ486x729:nimgの2つをNumpyのFFTOpenCVFFTで比較してみる。 また以下の結果はgoogle colab上でコードを実行した処理時間である。 コードごとの処理時間を計測するには%timeitを付け加えてセルを実行する。

Numpyの場合:

%timeit fft1 = np.fft.fft2(gray)
>14.4 ms ± 2.83 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit fft2 = np.fft.fft2(nimg)
>11.1 ms ± 2.75 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

OpenCVの場合:

%timeit dft1= cv2.dft(np.float32(gray),flags=cv2.DFT_COMPLEX_OUTPUT)
>3.32 ms ± 726 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit dft2= cv2.dft(np.float32(nimg),flags=cv2.DFT_COMPLEX_OUTPUT)
>4.13 ms ± 276 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

まずNumpyとOpenCVを比較するとNumpyでは10ms強の処理時間が、OpenCVでは3ms程度で3~4倍程度処理が速いことがわかる。 次に、画像サイズについては、Numpyは14ms→11msへと若干処理が速いがOpenCVでは3ms→4msでむしろ遅くなっている。

OpenCVの方が関数の記述は面倒だが、Numpyと比較して処理時間短縮の効果が期待できる。

3. まとめ

今回は画像フーリエ変換についてNumpyとOpenCVの処理時間の違いについて紹介した。