opencv初学(图像13)

文章介绍了傅里叶变换在图像处理中的应用,包括将图像转化为频率域,使用np.fft.fftshift调整频率分布,构造滤波器进行低通或高通滤波,以及通过cv2.idft进行逆变换恢复图像。通过实例展示了低通和高通滤波对图像的影响。
摘要由CSDN通过智能技术生成

傅里叶变换

详细介绍可参考(6 条消息) 傅里叶变换 - 搜索结果 - 知乎 (zhihu.com)

作用:将时域问题转化为频率问题,更好处理

滤波

步骤:

  1. 图片转化为频率域(借助cv2.dft(img, flags)

  1. 转化后的频率域中,频率为0的部分一般在左上角,将低频率区域放到中心区域,方便后期的利用掩码来滤波。(np.fft.fftshift(x, axis)

  1. 构造mask掩码作为滤波器使用

  1. 滤波

  1. 频率域转换回图片,低频率从中心转换回到左上角(cv2.idft(img),np.fft.ifftshift()、cv2.magnitude

频域变换

图片摘自1-傅里叶概述_哔哩哔哩_bilibili

import cv2
import matplotlib.pyplot as plt
import numpy as np

def cv_show(name,image):
    cv2.imshow(name,image)
    cv2.waitKey()
    cv2.destroyAllWindows()


img=cv2.imread('D:/BaiduNetdiskDownload/opencv/lena.png',0)
img_float32 = np.float32(img)

#DFT
dft=cv2.dft(img_float32,flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)
magnitude_spectrum_1=20*np.log(cv2.magnitude(dft[:,:,0],dft[:,:,1]))
magnitude_spectrum_2=20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))

plt.subplot(121),plt.imshow(magnitude_spectrum_1,cmap='gray'),plt.title("1")
plt.subplot(122),plt.imshow(magnitude_spectrum_2,cmap='gray'),plt.title("2")
plt.show()


API

参考原文链接:https://blog.csdn.net/dgvv4/article/details/121655105

cv2.dft(img, flags)

傅里叶变化函数

img:代表输入图像,opencv中输入图像必须转换成np.float32类型

flags:转换标识,通常为cv2.DFT_COMPLEX_OUTPUT,其他值如下:

np.fft.fftshift(x, axis)

x: 数组,代表输入的频谱图数据

axis: 可选,指定需要移动的轴。默认移动所有的轴返回位移之后的数组。

使用傅里叶变换后,在得到的频谱图中,频率为0的部分会在左上角,为了计算方便,我们通常将频率为0的部分转换到频谱图中心位置

cv2.magnitude(x, y)

x:数组类型,表示浮点型的x轴坐标,也就是实部

y:数组类型,表示浮点型的y轴坐标,也就是虚部

返回值为:x和y的平方和开根,

由于cv2.dft()返回的结果是双通道的(实部和虚部),通常需要转换成图像格式[0,255],才能正常显示频谱图。公式为:

20*np.log(cv2.magnitude(x, y))

cv2.idft(img)

傅里叶逆变换

img:代表输入处理后的频谱图像

在使用cv2.dft()获得频谱图时,将低频点从边缘移动到图像中间,现在要逆变换,得把低频点还原到原始位置,使用函数: np.fft.ifftshift(处理后的频谱图) ,之后才能将频谱图转变回空间图像。

注意,逆变换后的结果是包含实部和虚部的,仍需要使用cv2.magnitude函数进行处理

低通滤波示例

import cv2
import matplotlib.pyplot as plt
import numpy as np

def cv_show(name,image):
    cv2.imshow(name,image)
    cv2.waitKey()
    cv2.destroyAllWindows()

img=cv2.imread('D:/BaiduNetdiskDownload/opencv/lena.png',0)
img_float32 = np.float32(img)

#低通滤波
w,h=img.shape
w_center,h_center=int(w/2),int(h/2)#中心位置
mask=np.zeros((w,h,2),np.uint8)
mask[w_center-30:w_center+30,h_center-20:h_center+20]=1

#DFT
dft=cv2.dft(img_float32,flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)

#IDFT
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.subplot(122),plt.imshow(img_back,cmap='gray'),plt.title('Result')
plt.show()

高通滤波示例

import cv2
import matplotlib.pyplot as plt
import numpy as np

def cv_show(name,image):
    cv2.imshow(name,image)
    cv2.waitKey()
    cv2.destroyAllWindows()

img=cv2.imread('D:/BaiduNetdiskDownload/opencv/lena.png',0)
img_float32 = np.float32(img)

#高通滤波
w,h=img.shape
w_center,h_center=int(w/2),int(h/2)#中心位置
mask=np.ones((w,h,2),np.uint8)
mask[w_center-30:w_center+30,h_center-20:h_center+20]=0

#DFT
dft=cv2.dft(img_float32,flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift=np.fft.fftshift(dft)

#IDFT
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.subplot(122),plt.imshow(img_back,cmap='gray'),plt.title('Result')
plt.show()

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值