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()
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
andidft
scales the result by default. So, you should passDFT_SCALE
to one ofdft
oridft
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With