How do I get the exact result due to opencv?

I am using cv.dft to process the image and cv.idft to get it back after the tutorial here . However, the final image has a very large gray value, well over 255.

I check the code and find the extension is coming out of nowhere.

How does this happen? Can I return the exact value?

Code to reproduce:

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()

      

+3


source to share


1 answer


I would like to point you to the OpenCV documentation on the function cv2.idft

: http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#idft . There is a note at the end that says:

Note. None of dft

and idft

does not scale the result by default. So, you have to pass DFT_SCALE

to one of dft

or idft

explicitly to make these conversions mutually inverse.

What you are doing right now is to do DFT and IDFT without given a scale that allows both transforms to be reversible. This way, when you call cv2.idft

, make sure you pass the flag cv2.DFT_SCALE

.



In other words:

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

      

Since your image was already actually valuable to begin with, it's a good idea to pass a flag DFT_REAL_OUTPUT

to make sure your reverse is also real. All you do is calculate the FFT and then invert the result, so if you want to test that they are equivalent, make sure you do that.

+6


source







All Articles