当前位置:   article > 正文

python实现图像傅里叶变换_编程实现,为灰度图像添加高斯噪声,利用numpy库实现图像傅里叶变换及逆变换,所有图

编程实现,为灰度图像添加高斯噪声,利用numpy库实现图像傅里叶变换及逆变换,所有图

在做超分辨重建任务时,需要对重建图像做出评价,主要是人眼感官上的评价。这就需要我们从空域和频域两个方面对图像进行评价。下面给给出python实现的结果,并给出相应的代码。

图像(MxN)的二维离散傅立叶变换可以将图像由空间域变换到频域中去,空间域中用x,y来表示空间坐标,频域由u,v来表示频率,二维离散傅立叶变换的公式如下:

                      

在python中,numpy库的fft模块有实现好了的二维离散傅立叶变换函数,函数是fft2,输入一张灰度图,输出经过二维离散傅立叶变换后的结果,但是具体实现并不是直接用上述公式,而是用快速傅立叶变换。结果需要通过使用abs求绝对值才可以进行可视化,但是视觉效果并不理想,因为傅立叶频谱范围很大,所以要用log对数变换来改善视觉效果。

在使用log函数的时候,要写成log(1 + x) 而不是直接用log(x),这是为了避开对0做对数处理。

另外,图像变换的原点需要移动到频域矩形的中心,所以要对fft2的结果使用fftshift函数。最后也可以使用log来改善可视化效果。

代码如下:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. img = plt.imread('FFT/baboon.png')
  4. plt.subplot(231),plt.imshow(img),plt.title('picture')
  5. #根据公式转成灰度图
  6. img = 0.2126 * img[:,:,0] + 0.7152 * img[:,:,1] + 0.0722 * img[:,:,2]
  7. #显示灰度图
  8. plt.subplot(232),plt.imshow(img,'gray'),plt.title('original')
  9. #进行傅立叶变换,并显示结果
  10. fft2 = np.fft.fft2(img)
  11. plt.subplot(233),plt.imshow(np.abs(fft2),'gray'),plt.title('fft2')
  12. #将图像变换的原点移动到频域矩形的中心,并显示效果
  13. shift2center = np.fft.fftshift(fft2)
  14. plt.subplot(234),plt.imshow(np.abs(shift2center),'gray'),plt.title('shift2center')
  15. #对傅立叶变换的结果进行对数变换,并显示效果
  16. log_fft2 = np.log(1 + np.abs(fft2))
  17. plt.subplot(235),plt.imshow(log_fft2,'gray'),plt.title('log_fft2')
  18. #对中心化后的结果进行对数变换,并显示结果
  19. log_shift2center = np.log(1 + np.abs(shift2center))
  20. plt.subplot(236),plt.imshow(log_shift2center,'gray'),plt.title('log_shift2center')
  21. plt.show()

运行结果:

                   

  1. ###根据公式实现的二维离散傅立叶变换如下:
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. PI = 3.141591265
  5. img = plt.imread('temp.jpg')
  6. #根据公式转成灰度图
  7. img = 0.2126 * img[:,:,0] + 0.7152 * img[:,:,1] + 0.0722 * img[:,:,2]
  8. #显示原图
  9. plt.subplot(131),plt.imshow(img,'gray'),plt.title('original')
  10. #进行傅立叶变换,并显示结果
  11. fft2 = np.fft.fft2(img)
  12. log_fft2 = np.log(1 + np.abs(fft2))
  13. plt.subplot(132),plt.imshow(log_fft2,'gray'),plt.title('log_fft2')
  14. h , w = img.shape
  15. #生成一个同样大小的复数矩阵
  16. F = np.zeros([h,w],'complex128')
  17. for u in range(h):
  18. for v in range(w):
  19. res = 0
  20. for x in range(h):
  21. for y in range(w):
  22. res += img[x,y] * np.exp(-1.j * 2 * PI * (u * x / h + v * y / w))
  23. F[u,v] = res
  24. log_F = np.log(1 + np.abs(F))
  25. plt.subplot(133),plt.imshow(log_F,'gray'),plt.title('log_F')

直接根据公式实现复杂度很高,因为是四重循环,时间复杂度为O(M2N2),所以实际用的时候需要用快速傅立叶变换来实现。

python实现快速傅里叶变换:

  1. import cv
  2. def FFT(image,flag = 0):
  3. w = image.width
  4. h = image.height
  5. iTmp = cv.CreateImage((w,h),cv.IPL_DEPTH_32F,1)
  6. cv.Convert(image,iTmp)
  7. iMat = cv.CreateMat(h,w,cv.CV_32FC2)
  8. mFFT = cv.CreateMat(h,w,cv.CV_32FC2)
  9. for i in range(h):
  10. for j in range(w):
  11. if flag == 0:
  12. num = -1 if (i+j)%2 == 1 else 1
  13. else:
  14. num = 1
  15. iMat[i,j] = (iTmp[i,j]*num,0)
  16. cv.DFT(iMat,mFFT,cv.CV_DXT_FORWARD)
  17. return mFFT
  18. def IFFT(mat):
  19. mIFFt = cv.CreateMat(mat.rows,mat.cols,cv.CV_32FC2)
  20. cv.DFT(mat,mIFFt,cv.CV_DXT_INVERSE)
  21. return mIFFt
  22. def Restore(mat):
  23. w = mat.cols
  24. h = mat.rows
  25. size = (w,h)
  26. iRestore = cv.CreateImage(size,cv.IPL_DEPTH_8U,1)
  27. for i in range(h):
  28. for j in range(w):
  29. num = -1 if (i+j)%2 == 1 else 1
  30. iRestore[i,j] = mat[i,j][0]*num/(w*h)
  31. return iRestore
  32. def FImage(mat):
  33. w = mat.cols
  34. h = mat.rows
  35. size = (w,h)
  36. # iReal = cv.CreateImage(size,cv.IPL_DEPTH_8U,1)
  37. # iIma = cv.CreateImage(size,cv.IPL_DEPTH_8U,1)
  38. iAdd = cv.CreateImage(size,cv.IPL_DEPTH_8U,1)
  39. for i in range(h):
  40. for j in range(w):
  41. # iReal[i,j] = mat[i,j][0]/h
  42. # iIma[i,j] = mat[i,j][1]/h
  43. iAdd[i,j] = mat[i,j][1]/h + mat[i,j][0]/h
  44. return iAdd
  45. def Filter(mat,flag = 0,num = 10):
  46. mFilter = cv.CreateMat(mat.rows,mat.cols,cv.CV_32FC2)
  47. for i in range(mat.rows):
  48. for j in range(mat.cols):
  49. if flag == 0:
  50. mFilter[i,j] = (0,0)
  51. else:
  52. mFilter[i,j] = mat[i,j]
  53. for i in range(mat.rows/2-num,mat.rows/2+num):
  54. for j in range(mat.cols/2-num,mat.cols/2+num):
  55. if flag == 0:
  56. mFilter[i,j] = mat[i,j]
  57. else:
  58. mFilter[i,j] = (0,0)
  59. return mFilter
  60. image = cv.LoadImage('lena.jpg',0)
  61. mFFT = FFT(image)
  62. mIFFt = IFFT(mFFT)
  63. iAfter = FImage(mFFT)
  64. mLP = Filter(mFFT)
  65. mIFFt1=IFFT(mLP)
  66. iLP = FImage(mLP)
  67. iRestore = Restore(mIFFt1)
  68. mHP = Filter(mFFT,1)
  69. mIFFt2 = IFFT(mHP)
  70. iHP = FImage(mHP)
  71. iRestore2 = Restore(mIFFt2)
  72. cv.ShowImage('image',image)
  73. cv.ShowImage('iAfter',iAfter)
  74. cv.ShowImage('iLP',iLP)
  75. cv.ShowImage('iHP',iHP)
  76. cv.ShowImage('iRestore',iRestore)
  77. cv.ShowImage('iRestore2',iRestore2)
  78. cv.WaitKey(0)

opencv实现傅里叶变换:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import cv2
  4. img = cv2.imread('HR/baboon.png',0)
  5. dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
  6. dft_shift = np.fft.fftshift(dft)
  7. magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
  8. plt.subplot(121),plt.imshow(img, cmap = 'gray')
  9. plt.title('Input Image'), plt.xticks([]), plt.yticks([])
  10. plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
  11. plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
  12. plt.show()

参考文献:

【1】文献一

【2】文献二

 

 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号