###前提・実現したいこと
pythonで次のような画像どうしの畳み込み演算を行い、手ブレを再現したい。
詳細は下記の通りです。
ご教授のほどよろしくお願い致します。
###発生している問題
ImageJのFD Mathという機能で畳み込んだ場合と後述のPythonスクリプトでは、結果が異なります。
ImageJのように原画像の色合いを維持したいのですが、どうも畳み込みの結果を正規化する際に値がごく狭い範囲に補正され、白っぽくなっているような気がします。しかし解決方法がわかりませんでした。
- python
- ImageJ
###該当のソースコード
引数には原画像のファイル名や出力先のファイル名を適宜与えています。
Python
1import sys 2import numpy as np 3from PIL import Image 4from scipy import signal 5 6if len(sys.argv) != 5: 7 print('python blurer.py input fft_of_blur fft_of_original result') 8 sys.exit(1) 9 10# ブレを表現する画像をつくる 11size = 128 12half_size = int((size-1)/2) 13blur = Image.new('L', (size, size)) 14blur_pixels = blur.load() 15 16for x in range(half_size, half_size+5): 17 for y in range(half_size, half_size+20): 18 blur_pixels[half_size,y] = 255 19 20blur.save('blur.png') 21 22# FFTと畳み込み 23 24# ブレ画像 25blur_arr = np.array(blur) 26Z = np.fft.fft2(blur_arr) 27Z = np.fft.fftshift(Z) 28print(Z) 29P = np.log(np.abs(Z) + 1) 30P_norm = (P * 255.0) / np.amax(P) 31y = np.uint8(np.around(P_norm)) 32img_out = Image.fromarray(y) 33img_out.save(sys.argv[2]) 34 35# 原画像 36img_in = Image.open(sys.argv[1]) 37x = np.array(img_in.convert('L')) 38X = np.fft.fft2(x) 39X = np.fft.fftshift(X) 40print(X) 41P = np.log(np.abs(X) + 1) 42P_norm = (P * 255.0) / np.amax(P) 43y = np.uint8(np.around(P_norm)) 44print(y) 45img_out = Image.fromarray(y) 46img_out.save(sys.argv[3]) 47 48# 畳み込み結果 49W = np.fft.fftshift(np.fft.ifft2(Z*X)) 50print(W) 51P = np.log(np.abs(W) + 1) 52P_norm = P / np.amax(P) * 255 53y = np.uint8(np.around(P_norm)) 54print(y) 55img_out = Image.fromarray(y) 56img_out.save(sys.argv[4])
###補足情報
- Python 3.5.2 :: Anaconda 4.2.0
- numpy 1.13.1
- PIL.Image 1.1.7
追記(20170820)
回答により色の補正ができるようになり、問題解決しました。
最終的なソースコードを文献として残しておきます。
python
1import sys 2import numpy as np 3from PIL import Image 4from matplotlib import pylab as plt 5import cv2 6 7if len(sys.argv) != 2: 8 print('python blurer.py fft_of_original.png') 9 sys.exit(1) 10 11# ブレを表現する画像をつくる 12size = 128 13half_size = int((size - 1) / 2) 14blur = Image.new('L', (size, size)) 15blur_pixels = blur.load() 16 17for x in range(half_size, half_size + 5): 18 for y in range(half_size, half_size + 20): 19 blur_pixels[half_size, y] = 255 20 21blur.save('blur.png') 22 23# FFTと畳み込み 24 25# ブレ画像 26blur_arr = np.array(blur) 27Z = np.fft.fft2(blur_arr) 28Z = np.fft.fftshift(Z) 29P = np.log(np.abs(Z) + 1) 30P_norm = (P * 255.0) / np.amax(P) 31P_norm = (P_norm - np.amin(P_norm)) / np.amax(P_norm) * 255 32y = np.around(P_norm) 33blur_img = np.around(P_norm) 34print("BLUR MIN:%s"%np.min(y)) 35print("BLUR MAX:%s"%np.max(y)) 36img_out = Image.fromarray(y).convert('L') 37img_out.save("blur_arr.png") 38 39# 原画像 40img_in = Image.open(sys.argv[1]) 41x = np.array(img_in.convert('L')) 42dest = np.min(x) 43X = np.fft.fft2(x) 44X = np.fft.fftshift(X) 45P = np.log(np.abs(X) + 1) 46P_norm = (P * 255.0) / np.amax(P) 47y = np.around(P_norm) 48# dest = np.min(y) 49fftshift = np.around(P_norm) 50print("ORIGINAL MIN:%s"%np.min(y)) 51print("ORIGINAL MAX:%s"%np.max(y)) 52img_out = Image.fromarray(y).convert('L') 53img_out.save("fftshift.png") 54 55# 畳み込み結果 56W = np.fft.fftshift(np.fft.ifft2(Z * X)) 57P = np.log(np.abs(W) + 1) 58P_norm = P / np.amax(P) * 255 59src = np.min(P_norm) 60y = np.around(P_norm) 61print("CONV MIN:%s"%np.min(y)) 62print("CONV MAX:%s"%np.max(y)) 63img_out = Image.fromarray(y).convert('L') 64img_out.save("conv.png") 65 66# ガンマ補正 67 68gamma = np.log(src/255) / np.log(dest/255) 69 70print(gamma) 71lookUpTable = np.zeros((256, 1), dtype = 'uint8') 72for i in range(256): 73 if i == 0: 74 lookUpTable[i][0] = 255 * pow(float(0.000001) / 255, 1.0 / gamma) 75 else: 76 lookUpTable[i][0] = 255 * pow(float(i) / 255, 1.0 / gamma) 77 78img = cv2.imread('conv.png', 1) 79img_gamma = cv2.LUT(img, lookUpTable) 80cv2.imwrite('conv-lut.png', img_gamma)
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/08/20 03:49