dft.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #!/usr/bin/env python
  2. '''
  3. sample for disctrete fourier transform (dft)
  4. USAGE:
  5. dft.py <image_file>
  6. '''
  7. # Python 2/3 compatibility
  8. from __future__ import print_function
  9. import cv2
  10. import numpy as np
  11. import sys
  12. def shift_dft(src, dst=None):
  13. '''
  14. Rearrange the quadrants of Fourier image so that the origin is at
  15. the image center. Swaps quadrant 1 with 3, and 2 with 4.
  16. src and dst arrays must be equal size & type
  17. '''
  18. if dst is None:
  19. dst = np.empty(src.shape, src.dtype)
  20. elif src.shape != dst.shape:
  21. raise ValueError("src and dst must have equal sizes")
  22. elif src.dtype != dst.dtype:
  23. raise TypeError("src and dst must have equal types")
  24. if src is dst:
  25. ret = np.empty(src.shape, src.dtype)
  26. else:
  27. ret = dst
  28. h, w = src.shape[:2]
  29. cx1 = cx2 = w/2
  30. cy1 = cy2 = h/2
  31. # if the size is odd, then adjust the bottom/right quadrants
  32. if w % 2 != 0:
  33. cx2 += 1
  34. if h % 2 != 0:
  35. cy2 += 1
  36. # swap quadrants
  37. # swap q1 and q3
  38. ret[h-cy1:, w-cx1:] = src[0:cy1 , 0:cx1 ] # q1 -> q3
  39. ret[0:cy2 , 0:cx2 ] = src[h-cy2:, w-cx2:] # q3 -> q1
  40. # swap q2 and q4
  41. ret[0:cy2 , w-cx2:] = src[h-cy2:, 0:cx2 ] # q2 -> q4
  42. ret[h-cy1:, 0:cx1 ] = src[0:cy1 , w-cx1:] # q4 -> q2
  43. if src is dst:
  44. dst[:,:] = ret
  45. return dst
  46. if __name__ == "__main__":
  47. if len(sys.argv) > 1:
  48. im = cv2.imread(sys.argv[1])
  49. else:
  50. im = cv2.imread('../data/baboon.jpg')
  51. print("usage : python dft.py <image_file>")
  52. # convert to grayscale
  53. im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
  54. h, w = im.shape[:2]
  55. realInput = im.astype(np.float64)
  56. # perform an optimally sized dft
  57. dft_M = cv2.getOptimalDFTSize(w)
  58. dft_N = cv2.getOptimalDFTSize(h)
  59. # copy A to dft_A and pad dft_A with zeros
  60. dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64)
  61. dft_A[:h, :w, 0] = realInput
  62. # no need to pad bottom part of dft_A with zeros because of
  63. # use of nonzeroRows parameter in cv2.dft()
  64. cv2.dft(dft_A, dst=dft_A, nonzeroRows=h)
  65. cv2.imshow("win", im)
  66. # Split fourier into real and imaginary parts
  67. image_Re, image_Im = cv2.split(dft_A)
  68. # Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
  69. magnitude = cv2.sqrt(image_Re**2.0 + image_Im**2.0)
  70. # Compute log(1 + Mag)
  71. log_spectrum = cv2.log(1.0 + magnitude)
  72. # Rearrange the quadrants of Fourier image so that the origin is at
  73. # the image center
  74. shift_dft(log_spectrum, log_spectrum)
  75. # normalize and display the results as rgb
  76. cv2.normalize(log_spectrum, log_spectrum, 0.0, 1.0, cv2.NORM_MINMAX)
  77. cv2.imshow("magnitude", log_spectrum)
  78. cv2.waitKey(0)
  79. cv2.destroyAllWindows()