opencv python 傅里叶变换的使用


Posted in Python onJuly 21, 2018

理论

傅立叶变换用于分析各种滤波器的频率特性,对于图像,2D离散傅里叶变换(DFT)用于找到频域.快速傅里叶变换(FFT)的快速算法用于计算DFT.

于一个正弦信号,x(t)=Asin(2πft),我们可以说 f 是信号的频率,如果它的频率域被接受,我们可以看到 f 的峰值.如果信号被采样来形成一个离散信号,我们得到相同的频率域,但是在[−π,π] or [0,2π]范围内是周期性的 (or [0,N] for N-point DFT).

可以将图像视为在两个方向上采样的信号.因此,在X和Y方向上进行傅里叶变换可以得到图像的频率表示.

更直观的是,对于正弦信号,如果振幅在短时间内变化得非常快,你可以说它是一个高频信号.如果它变化缓慢,它是一个低频信号,可以把同样的想法扩展到图片上,边和噪声是图像中的高频内容,如果振幅没有很大的变化,那就是低频分量.

Numpy中的傅里叶变换

np.fft.fft2()

第一个参数是输入图像,它是灰度图像

第二个参数是可选的,它决定了输出数组的大小,如果它大于输入图像的大小,则输入图像在计算FFT之前填充了0.如果它小于输入图像,输入图像将被裁剪,如果没有参数传递,输出数组的大小将与输入相同.

一旦得到结果,零频率分量(DC分量)将位于左上角。 如果要将其置于中心位置,则需要在两个方向上将结果移动N2.np.fft.fftshift(),一旦你找到频率变换,你就能找到大小谱.

代码:

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

img = cv2.imread('img.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()

opencv python 傅里叶变换的使用

可以在中心看到更多的白色区域,表示低频率的内容更多.

现在可以在频域做一些运算,比如高通滤波和重建图像也就是找到逆DFT,只需用一个矩形窗口大小的60x60来移除低频部分,使用np.fft.ifftshift()应用反向移动,使DC组件再次出现在左上角,然后使用np.ifft2()函数找到反FFT,结果将会是一个复数,可以取它的绝对值.

代码:

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

img = cv2.imread('img.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 = int(rows/2) , int(cols/2)
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
f_ishift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f_ishift)
img_back = np.abs(img_back)


plt.subplot(221),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(222),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(223),plt.imshow(img_back)
plt.title('Result in JET'), plt.xticks([]), plt.yticks([])
plt.subplot(224),plt.imshow(img_back, cmap = 'gray')
plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
plt.show()

opencv python 傅里叶变换的使用

结果表明,高通滤波是一种边缘检测操作.

OpenCV中的傅里叶变换

OpenCV提供了cv.dft()cv.idft()函数.它返回与前面相同的结果,但是有两个通道.第一个通道将会有结果的实部,第二个通道将会有一个虚部.

输入图像首先应该转换为np.float32

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

img = cv2.imread('img.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()

opencv python 傅里叶变换的使用

也可以使用cv.cartToPolar(),它可以在一次拍摄中同时返回大小和相位.

现在我们要做的是逆DFT.这次我们将移除图像中的高频内容,即我们将LPF应用到图像中.它实际上模糊了图像.为此,我们先创建一个具有高值(1)低频率的掩模,即我们通过低频内容,而在高频区域则是0。

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

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

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

rows, cols = img.shape
crow,ccol = int(rows/2) , int(cols/2)

# create a mask first, center square is 1, remaining all zeros
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1

# apply mask and inverse DFT
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()

opencv python 傅里叶变换的使用

NOTE:

OpenCV函数cv.dft()cv.idft()比Numpy函数更快.但是Numpy功能更加用户友好.

Fourier Transform

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之dict()的操作方法
Sep 24 Python
简单的Python抓taobao图片爬虫
Oct 26 Python
python检查字符串是否是正确ISBN的方法
Jul 11 Python
详解duck typing鸭子类型程序设计与Python的实现示例
Jun 03 Python
Python字典及字典基本操作方法详解
Jan 30 Python
python中单例常用的几种实现方法总结
Oct 13 Python
浅谈python函数调用返回两个或多个变量的方法
Jan 23 Python
使用WingPro 7 设置Python路径的方法
Jul 24 Python
解决Django删除migrations文件夹中的文件后出现的异常问题
Aug 31 Python
Python Socket TCP双端聊天功能实现过程详解
Jun 15 Python
Django中Aggregation聚合的基本使用方法
Jul 09 Python
python基础之//、/与%的区别详解
Jun 10 Python
Numpy中的mask的使用
Jul 21 #Python
Flask框架使用DBUtils模块连接数据库操作示例
Jul 20 #Python
Flask框架WTForm表单用法示例
Jul 20 #Python
Python使用pymongo模块操作MongoDB的方法示例
Jul 20 #Python
Python闭包函数定义与用法分析
Jul 20 #Python
Django rest framework工具包简单用法示例
Jul 20 #Python
Django 中使用流响应处理视频的方法
Jul 20 #Python
You might like
Thinkphp搜索时首页分页和搜索页保持条件分页的方法
2014/12/05 PHP
php文件类型MIME对照表(比较全)
2016/10/07 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
用JavaScript玩转游戏物理(一)运动学模拟与粒子系统
2010/06/19 Javascript
jQuery中调用WebService方法小结
2011/03/28 Javascript
Json序列化和反序列化方法解析
2013/12/19 Javascript
js生成动态表格并为每个单元格添加单击事件的方法
2014/04/14 Javascript
AngularGauge 属性解析详解
2016/09/06 Javascript
Bootstrap和Java分页实例第一篇
2016/12/23 Javascript
node.js平台下的mysql数据库配置及连接
2017/03/31 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
2017/04/21 jQuery
js使用xml数据载体实现城市省份二级联动效果
2017/11/08 Javascript
详解vue-loader在项目中是如何配置的
2018/06/04 Javascript
Vue.js更改调试地址端口号的实例
2018/09/19 Javascript
浅谈Fetch 数据交互方式
2018/12/20 Javascript
超简单的微信小程序轮播图
2019/11/22 Javascript
理解JavaScript中的对象
2020/08/25 Javascript
vue实现lodop打印功能的示例
2020/11/11 Javascript
Vue 实现一个简单的鼠标拖拽滚动效果插件
2020/12/10 Vue.js
使用urllib库的urlretrieve()方法下载网络文件到本地的方法
2018/12/19 Python
python3+selenium实现126邮箱登陆并发送邮件功能
2019/01/23 Python
python实现简易版学生成绩管理系统
2020/06/22 Python
英国女士和男士时尚服装网上购物:Top Labels Online
2018/03/25 全球购物
园长自我鉴定
2013/10/06 职场文书
导游实习生自荐书
2014/01/28 职场文书
员工拓展培训方案
2014/02/15 职场文书
煤矿班组长竞聘书
2014/03/31 职场文书
创文明城市标语
2014/06/16 职场文书
销售人员求职信
2014/07/22 职场文书
英文演讲稿开场白
2014/08/25 职场文书
政风行风评议个人心得体会
2014/10/29 职场文书
安全保证书
2015/01/16 职场文书
2016春节放假通知范文
2015/08/18 职场文书
Nginx设置HTTPS的方法步骤 443证书配置方法
2022/03/21 Servers
Mysql超详细讲解死锁问题的理解
2022/04/01 MySQL
django项目、vue项目部署云服务器的详细过程
2022/07/23 Servers