opencv/samples/python/dft.py

112 lines
2.7 KiB
Python
Raw Normal View History

#!/usr/bin/env python
2013-03-29 22:37:00 +01:00
2015-12-15 00:33:55 +01:00
'''
sample for disctrete fourier transform (dft)
USAGE:
dft.py <image_file>
'''
# Python 2/3 compatibility
from __future__ import print_function
2013-03-29 22:37:00 +01:00
import cv2
import numpy as np
import sys
def shift_dft(src, dst=None):
'''
Rearrange the quadrants of Fourier image so that the origin is at
2013-04-05 17:52:42 +02:00
the image center. Swaps quadrant 1 with 3, and 2 with 4.
2013-03-29 22:37:00 +01:00
src and dst arrays must be equal size & type
'''
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
if dst is None:
dst = np.empty(src.shape, src.dtype)
elif src.shape != dst.shape:
raise ValueError("src and dst must have equal sizes")
elif src.dtype != dst.dtype:
raise TypeError("src and dst must have equal types")
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
if src is dst:
ret = np.empty(src.shape, src.dtype)
else:
ret = dst
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
h, w = src.shape[:2]
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
cx1 = cx2 = w/2
cy1 = cy2 = h/2
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# if the size is odd, then adjust the bottom/right quadrants
if w % 2 != 0:
cx2 += 1
if h % 2 != 0:
2013-04-05 17:52:42 +02:00
cy2 += 1
2013-03-29 22:37:00 +01:00
# swap quadrants
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# swap q1 and q3
ret[h-cy1:, w-cx1:] = src[0:cy1 , 0:cx1 ] # q1 -> q3
ret[0:cy2 , 0:cx2 ] = src[h-cy2:, w-cx2:] # q3 -> q1
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# swap q2 and q4
ret[0:cy2 , w-cx2:] = src[h-cy2:, 0:cx2 ] # q2 -> q4
ret[h-cy1:, 0:cx1 ] = src[0:cy1 , w-cx1:] # q4 -> q2
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
if src is dst:
dst[:,:] = ret
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
return dst
if __name__ == "__main__":
2013-04-05 17:52:42 +02:00
2015-12-15 00:33:55 +01:00
if len(sys.argv) > 1:
2013-03-29 22:37:00 +01:00
im = cv2.imread(sys.argv[1])
2015-12-15 00:33:55 +01:00
else:
2014-09-13 16:28:41 +02:00
im = cv2.imread('../data/baboon.jpg')
print("usage : python dft.py <image_file>")
2013-03-29 22:37:00 +01:00
# convert to grayscale
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
h, w = im.shape[:2]
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
realInput = im.astype(np.float64)
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# perform an optimally sized dft
dft_M = cv2.getOptimalDFTSize(w)
dft_N = cv2.getOptimalDFTSize(h)
# copy A to dft_A and pad dft_A with zeros
dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64)
dft_A[:h, :w, 0] = realInput
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# no need to pad bottom part of dft_A with zeros because of
# use of nonzeroRows parameter in cv2.dft()
cv2.dft(dft_A, dst=dft_A, nonzeroRows=h)
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
cv2.imshow("win", im)
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# Split fourier into real and imaginary parts
image_Re, image_Im = cv2.split(dft_A)
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
magnitude = cv2.sqrt(image_Re**2.0 + image_Im**2.0)
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# Compute log(1 + Mag)
log_spectrum = cv2.log(1.0 + magnitude)
2013-04-05 17:52:42 +02:00
2013-03-29 22:37:00 +01:00
# Rearrange the quadrants of Fourier image so that the origin is at
# the image center
shift_dft(log_spectrum, log_spectrum)
# normalize and display the results as rgb
2013-04-12 15:39:16 +02:00
cv2.normalize(log_spectrum, log_spectrum, 0.0, 1.0, cv2.NORM_MINMAX)
2013-03-29 22:37:00 +01:00
cv2.imshow("magnitude", log_spectrum)
cv2.waitKey(0)
cv2.destroyAllWindows()