dft.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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 numpy as np
  10. import cv2 as cv
  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. def main():
  47. if len(sys.argv) > 1:
  48. fname = sys.argv[1]
  49. else:
  50. fname = 'baboon.jpg'
  51. print("usage : python dft.py <image_file>")
  52. im = cv.imread(cv.samples.findFile(fname))
  53. # convert to grayscale
  54. im = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
  55. h, w = im.shape[:2]
  56. realInput = im.astype(np.float64)
  57. # perform an optimally sized dft
  58. dft_M = cv.getOptimalDFTSize(w)
  59. dft_N = cv.getOptimalDFTSize(h)
  60. # copy A to dft_A and pad dft_A with zeros
  61. dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64)
  62. dft_A[:h, :w, 0] = realInput
  63. # no need to pad bottom part of dft_A with zeros because of
  64. # use of nonzeroRows parameter in cv.dft()
  65. cv.dft(dft_A, dst=dft_A, nonzeroRows=h)
  66. cv.imshow("win", im)
  67. # Split fourier into real and imaginary parts
  68. image_Re, image_Im = cv.split(dft_A)
  69. # Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
  70. magnitude = cv.sqrt(image_Re**2.0 + image_Im**2.0)
  71. # Compute log(1 + Mag)
  72. log_spectrum = cv.log(1.0 + magnitude)
  73. # Rearrange the quadrants of Fourier image so that the origin is at
  74. # the image center
  75. shift_dft(log_spectrum, log_spectrum)
  76. # normalize and display the results as rgb
  77. cv.normalize(log_spectrum, log_spectrum, 0.0, 1.0, cv.NORM_MINMAX)
  78. cv.imshow("magnitude", log_spectrum)
  79. cv.waitKey(0)
  80. print('Done')
  81. if __name__ == '__main__':
  82. print(__doc__)
  83. main()
  84. cv.destroyAllWindows()