高速Fourier変換と逆高速Fourier変換を画像にかましてみる。
import sys import numpy as np from matplotlib import pyplot as plt img = plt.imread(sys.argv[1], 1) # FFT f = np.fft.fft2(img) # IFFT img_back = np.fft.ifft2(f) # complex -> uint8 img_back = img_back.real img_back = img_back.astype(np.uint8) plt.subplot(121), plt.imshow(img) plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(img_back) plt.title('IFFT after FFT'), plt.xticks([]), plt.yticks([]) plt.show()
以下のようにほぼ同じ画像になる。実際にはRGBの各チャンネルの中にちょっとだけ誤差はあるのだが。
また、imshow は pyplot にも cv2 にもあるが、pyplot.imshow で表示するなら pyplot.imread で画像を読みこむべきのようだ。というか混ぜると色相が変になった...。
理論上のFourie変換と逆変換ならキッチリ戻ってくるが、計算機での計算なので誤差が出る。虚部もあるし、実部も理論値からはちょっと揺らいでいるはずだ。ということで、ユニバーサル関数で良い感じにした。
NumPy配列を対象としたユニバーサル関数 | hydroculのメモにもあるが、mapとかイテレータみたいなもので各要素を変更したかったが、そういうことができそうにはなくて、大分考えてしまった...。最初は実部をとって整数に落として、0から255に収まるように補正をするようにforループを書いたが、まぁ、イマイチだね。そこまでやっても、numpy,array.astype で型変換を明示しないと、複素素型の配列のままで、pyplot.imshow に怒られた。面倒くさい。numpy は中身が C だから、こういう時に急に型というものを意識させられる。