Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get accurate idft result from opencv?

I use cv.dft to process an image and cv.idft to get it back following the tutorial here. However, the final image has very large gray value, which is much more than 255.

I check the code and find the enlargement comes from nowhere.

How does this happen? Can I get the accurate value back?

Code for reproducing:

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('test.bmp',0) # change for your own test image

dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
f_ishift = np.fft.ifftshift(dft_shift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

print (img_back.max(), img_back.min()) # too large!!!!

plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img_back, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()
like image 386
thundertrick Avatar asked May 08 '15 15:05

thundertrick


1 Answers

I would like to point you to the OpenCV documentation on the cv2.idft function: http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#idft . There is a note at the end of it, which says:

Note: None of dft and idft scales the result by default. So, you should pass DFT_SCALE to one of dft or idft explicitly to make these transforms mutually inverse.

What you are doing right now is taking the DFT and IDFT without accounting for the scale that allows both of the transforms to be invertible. As such, when you call cv2.idft, make sure you pass the cv2.DFT_SCALE flag.

In other words:

img_back = cv2.idft(f_ishift, flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT)

Because your image was already real-valued to begin with, it's a good idea to pass the DFT_REAL_OUTPUT flag as well to ensure that your inverse is also real-valued. All you're doing is computing the FFT, then the inverse of the result, so if you want to check to see that they're equivalent, make sure you do that.

like image 166
rayryeng Avatar answered Nov 14 '22 05:11

rayryeng