I'm new to all of this, I would like to get a magnitude spectrum from an image and then rebuild the image from a modified magnitude spectrum.. But for now i'am getting a very dark reconstitution.
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('IMG.jpg',0)
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
m, a = np.log(cv2.cartToPolar(dft_shift[:,:,0],dft_shift[:,:,1]))
# do somthing with m
x, y = cv2.polarToCart(np.exp(m), a)
back = cv2.merge([x, y])
f_ishift = np.fft.ifftshift(back)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])
plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(m, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_back, cmap = 'gray')
plt.title('result'), plt.xticks([]), plt.yticks([])
plt.show()
the result
Can you guys help me figure out why is this so dark.
Thank in advance :)
EDIT
I tryed to normalise the image, but it's not working. I'm still having a very dark image.
import numpy as np
import cv2
from matplotlib import pyplot as plt
img = cv2.imread('IMG.jpg',0)
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
m, a = np.log1p(cv2.cartToPolar(dft_shift[:,:,0],dft_shift[:,:,1]))
# modify m, then use the modify m to reconstruct
x, y = cv2.polarToCart(np.expm1(m), a)
back = cv2.merge([x, y])
f_ishift = np.fft.ifftshift(back)
img_back = cv2.idft(f_ishift, flags=cv2.DFT_SCALE)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])
min, max = np.amin(img, (0,1)), np.amax(img, (0,1))
print(min,max)
# re-normalize to 8-bits
min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
print(min,max)
img_back = cv2.normalize(img_back, None, alpha=0, beta=252, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
print(min,max)
plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(m, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_back, cmap = 'gray')
plt.title('result'), plt.xticks([]), plt.yticks([])
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
output:
0 252
0.36347726 5867.449
0 252
I would like to modify the magnitude spectrum and used the modify version to reconstruct the image.
Magnitude Method. Calculates the magnitude of 2D vectors.
1) Fast Fourier Transform to transform image to frequency domain. 2) Moving the origin to centre for better visualisation and understanding. 3) Apply filters to filter out frequencies. 5) Inverse transform using Inverse Fast Fourier Transformation to get image back from the frequency domain.
As we are only concerned with digital images, we will restrict this discussion to the Discrete Fourier Transform (DFT). The DFT is the sampled Fourier Transform and therefore does not contain all frequencies forming an image, but only a set of samples which is large enough to fully describe the spatial domain image.
If you need to modify the magnitude by raising it to a power near 1 (called coefficient rooting or alpha rooting), then it is just a simple modification of my code above using Python/OpenCV. Simply add cv2.pow(mag, 1.1) before converting the magnitude and phase back to real and imaginary components.
Input:
import numpy as np
import cv2
# read input as grayscale
img = cv2.imread('lena.png', 0)
# convert image to floats and do dft saving as complex output
dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)
# apply shift of origin from upper left corner to center of image
dft_shift = np.fft.fftshift(dft)
# extract magnitude and phase images
mag, phase = cv2.cartToPolar(dft_shift[:,:,0], dft_shift[:,:,1])
# get spectrum for viewing only
spec = np.log(mag) / 30
# NEW CODE HERE: raise mag to some power near 1
# values larger than 1 increase contrast; values smaller than 1 decrease contrast
mag = cv2.pow(mag, 1.1)
# convert magnitude and phase into cartesian real and imaginary components
real, imag = cv2.polarToCart(mag, phase)
# combine cartesian components into one complex image
back = cv2.merge([real, imag])
# shift origin from center to upper left corner
back_ishift = np.fft.ifftshift(back)
# do idft saving as complex output
img_back = cv2.idft(back_ishift)
# combine complex components into original image again
img_back = cv2.magnitude(img_back[:,:,0], img_back[:,:,1])
# re-normalize to 8-bits
min, max = np.amin(img_back, (0,1)), np.amax(img_back, (0,1))
print(min,max)
img_back = cv2.normalize(img_back, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8U)
cv2.imshow("ORIGINAL", img)
cv2.imshow("MAG", mag)
cv2.imshow("PHASE", phase)
cv2.imshow("SPECTRUM", spec)
cv2.imshow("REAL", real)
cv2.imshow("IMAGINARY", imag)
cv2.imshow("COEF ROOT", img_back)
cv2.waitKey(0)
cv2.destroyAllWindows()
# write result to disk
cv2.imwrite("lena_grayscale_opencv.png", img)
cv2.imwrite("lena_grayscale_coefroot_opencv.png", img_back)
Original Grayscale:
Coefficient Rooting Result:
Here is an animation showing the differences (created using ImageMagick):
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