十五天掌握OpenCV——傅里叶变换

  1. 用处:分析不同滤波器的频率特性。
  2. 2D离散傅里叶变化(DFT):分析图像的频域特性。
  3. 快速傅里叶变换(FFT):实现DFT的快速算法。
  4. 图像中,边界点或者噪声处的频率幅度变化大,是高频分量。

Numpy中的傅里叶变换

  1. FFT包:实现快速傅里叶变换。
  2. np.fft.fft2(灰度图像名,输出数组大小) ——解释:对信号进行频率转换,输出复杂的数组。
  3. np.fft.fftshift() ——解释:输出图像中左上角频率为0的部分(直流分量)移到中心。

代码演示

#coding=utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt

img=cv2.imread('222.jpg',0)
f=np.fft.fft2(img)
fshift=np.fft.fftshift(f)
magnitude_spectrum=20*np.log(np.abs(fshift))

plt.subplot(121),plt.imshow(img,cmap='gray')
plt.title('input image'),plt.xticks([]),plt.yticks([])
plt.subplot(122),plt.imshow(magnitude_spectrum,cmap='gray')
plt.title('magnitude spectrum'),plt.xticks([]),plt.yticks([])

plt.show()

1
频域变换(高通滤波 重建图像)

  1. 60的矩形窗口对图像掩模,去除低频分量。
  2. np.fft.ifftshift() 逆平移操作。
  3. 直流分量位于左上角,np.ifft2() FFT逆变换。
  4. 得到 复杂数字,取绝对值。

代码演示

#coding=utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt

img=cv2.imread('222.jpg',0)
f=np.fft.fft2(img)
fshift=np.fft.fftshift(f)
magnitude_spectrum=20*np.log(np.abs(fshift))

rows,cols=img.shape
crow,ccol=rows/2,cols/2
fshift[crow-30:crow+30,ccol-30:ccol+30]=0
f_ishift=np.fft.ifftshift(fshift)
img_back=np.fft.sfft2(f_ishift)
img_back=np.abs(img_back) #取绝对值

plt.subplot(121),plt.imshow(img,cmap='gray')
plt.title('input image'),plt.xticks([]),plt.yticks([])
plt.subplot(122),plt.imshow(img_back,cmap='gray')
plt.title('magnitude spectrum'),plt.xticks([]),plt.yticks([])
plt.subplot(123),plt.imshow(img_back)
plt.title('result in jet'),plt.xticks([]),plt.yticks([])
plt.show()
  1. 高通滤波:边界检测操作。

OpenCV中的傅里叶变换

cv2.dft() cv2.idft() 双通道:第一个通道是结果的实数部分,第二个通道是结果的虚数部分。
输入图像:转换成np.float32格式。
cv2.cartToPolar() ——解释:返回幅度和相位。

代码演示

#coding=utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt

img=cv2.imread('pingguo.jpg',0)

dft=cv2.dft(np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)

magnitude_spectrum=20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))

plt.subplot(121),plt.imshow(img,cmap='gray')
plt.title('input image'),plt.xticks([]),plt.yticks([])
plt.subplot(122),plt.imshow(magnitude_spectrum,cmap='gray')
plt.title('magnitude spectrum'),plt.xticks([]),plt.yticks([])

plt.show()

2

代码演示

#coding=utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt

img=cv2.imread('pingguo.jpg',0)

rows,cols=img.shape
crow,ccol=rows/2,cols/2

dft=cv2.dft(np.float32(img),flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)

mask=np.zeros((rows,cols,2),np.uint8)
mask[crow-10:crow+10,ccol-10:ccol+10]=1

fshift=dft_shift*mask
f_ishift=np.fft.ifftshift(fshift)
img_back=cv2.idft(f_ishift)
img_back=cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

plt.subplot(121),plt.imshow(img,cmap='gray')
plt.title('input image'),plt.xticks([]),plt.yticks([])
plt.subplot(122),plt.imshow(img_back,cmap='gray')
plt.title('magnitude spectrum'),plt.xticks([]),plt.yticks([])

plt.show()

DFT性能优化

数组大小为2,3,5的指数时DFT效率很高。
修改输入图像的大小(补0),OpenCV手动补0,numpy自动补0。
cv2.getOptimalDFTSize() ——解释:确定最佳大小。
cv2.copyMakeBorder(img,0,bottom,0,right,bordertype,value=0) ——解释:改善数组大小。

拉普拉斯算子是高通滤波器

通过傅里叶变换得出结果。高通滤波器(HPF) 低通滤波器(LPF)

代码演示

#coding=utf-8
import cv2
import numpy as np
from matplotlib import pyplot as plt

mean_filter=np.ones((3,3))

x=cv2.getGaussianKernel(5,10) #生成一个高斯滤波器
gaussian=x*x.T #转置矩阵
scharr=np.array([[-3,0,3],
                 [-10,0,10],
                 [-3,0,3]])  # 不同边缘检测滤波器
sobel_x=np.array([[-1,0,1],
                  [-2,0,2],
                  [-1.0,1]]) 
sobel_y=np.array([[-1,-2,-1],
                  [0,0,0],
                  [1,2,1]])
laplacian=np.array([[0,1,0],
                    [1,-4,1],
                    [0,1,0]])
filters=[mean_filter,gaussian,laplacian,sobel_x,sobel_y,scharr]
filter_name=['mean_filter','gaussian','laplacian','sobel_x','sobel_y','scharr_x']
fft_filters=[np.fft.fft2(x) for x in filters]
fft_shift=[np.fft.fftshift(y) for y in fft_filters]
mag_spectrum=[np.log(np.abs(z)+1) for z in fft_shift]

for i in range(6):
    plt.subplot(2,3,i+1),plt.imshow(mag_spectrum[i],cmap='gray')
    plt.title(filter_name[i]),plt.xticks([]),plt.yticks([])
    
plt.show()
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值