当前位置: 首页 > news >正文

[激光原理与应用-126]:傅里叶变化与频域分析

目录

一、什么是傅里叶变换

1.1 基本概念

(1)首先,先看时域图像:

(2)接下来,频域波形

(3)傅里叶变换

1.2 应用

(1)离散傅里叶变换在图像处理领域的应用:

二、代码编写:傅里叶变换与逆傅里叶变换

2.1 、OpenCV实现傅里叶变换

2.2 OpenCV实现逆傅里叶变换

2.3 Numpy实现傅里叶变换

2.4、Numpy实现逆傅里叶变换

三、应用实践:低通滤波与高通滤波

3.1 低通滤波:滤除高频分量 ——模糊图像(使用OpenCV)

3.2 高通滤波  ——滤除低频分量 - 锐化图像(使用OpenCV)


一、什么是傅里叶变换

1.1 基本概念

傅里叶原理表明:任何连续测量的时序或信号(时域信号),都可以表示为不同频率正弦波信号无限叠加(积分)。也就是说,傅里叶变换是一种特殊的积分变换,它能将满足一定条件的某个函数(时域信号)表示成正弦基函数线性组合或者积分

不同的研究领域,傅里叶变换具有多种不同的变体形式,如连续傅里叶变换离散傅里叶变换

(看一张动态图,原作者: 傅里叶分析之掐死教程(完整版)更新于2014.06.06 - 知乎) (动态图的开始部分很清晰的展现了:红色曲线可以由众多条(或者无数条)蓝色的正弦函数以及余弦函数叠加而成)
(再看一张老面孔) 在数字图像领域,我们一般使用的都是二维的灰度图像,所以这里从二维的傅里叶变换说起。

(1)首先,先看时域图像:

他是我们经常见到与接触的一种函数(方波信号),称它为 f(t):


从大图中可以看到,这条线是由所有的正弦波叠加而成的总和,反过来说就是,所有的正弦波都是这条总和波的分量。其中,频率最低的排在最前面,越往后,频率越高(即上下跳动越活越),并且,每一条波的振幅都不同(因为波形的高度不同)。同时,我们也发现在所有的正弦波中,有很多分量是直线,那是因为时域图像中的 f(t) 并不需要某种特定频率的正弦波,所以表现为直线。

(2)接下来,频域波形

我们从正弦波的侧面看过去,便是 f(t) 在频域的样子(终于到这一步了)

在频域上,自变量为正弦波分量的频率,因变量为振幅,他们两形成的函数 F(w),也就是频域图像。这时,一个时域——频域的映射就完成了。

(3)傅里叶变换

让我们在回顾一下文章开头的动图的最后一张:

由 时域上的红色图像 映射到了 频域上的蓝色图像,这便是傅里叶变换所做的事。

1.2 应用

(1)离散傅里叶变换在图像处理领域的应用:

对于数字图像这种离散的信号,频率大小表示信号变化的剧烈程度或者说是信号变化的快慢
频率越大,变化越剧烈,频率越小,信号越平缓。

对应到图像中,高频信号往往是图像中的边缘信号和噪声信号,而低频信号包含图像变化缓慢的图像轮廓及背景等信号。

因此,我们可以做相应的锐化和模糊的处理:提出其中的高频分量做傅里叶逆变换得到的就是锐化的结果(高通滤波器)。 提出其中的低频分量做傅里叶逆变换得到的就是模糊的结果(低通滤波器)。

另外,需要特别注意的一点是:

截取频域图中的任何一个区域对应的都是原来的整张图的区域,而不是对应的局部区域。

二、代码编写:傅里叶变换与逆傅里叶变换

【Numpy与OpenCV均可实现傅里叶变换与逆傅里叶变换】

2.1 、OpenCV实现傅里叶变换

OpenCV API:

dst = cv2.dft (src , flags)

参数:

src:输入图像,需要转换格式为np.float32,可以为实数矩阵或者复数矩阵
flags:转换标志
(如DFT_COMPLEX_OUTPUT,对一维或二维实数数组正变换,输出一个同样尺寸的复数矩阵)
(DFT_REAL_OUTPUT,对一维或二维复数数组反变换,通常输出同样尺寸的复矩阵)
返回结果:是双通道的,第一个的结果是虚数部分,第二个通道的结果是实数部分
其他函数:

np.fft.fftshift(dst):将图像的低频部分移动到图像的中心
返回值 = cv2.magnitude(参数1, 参数2)——将复数结果转换为幅值
参数1:浮点型X坐标值,也就是实部
参数2:浮点型Y坐标值,也就是虚部

【代码编写】

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

# 以灰度形式读入
img = cv2.imread('img\qiqiqi.png', 0)

# 使用cv2.dft()进行傅里叶变换
dst = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)

# 将变换后图像的低频部分转移到图像的中心(低频信号在原点)
dst_center = np.fft.fftshift(dst)

# 使用cv2.magnitude将实部和虚部转换为实部,乘以20是为了使得结果更大
result = 20 * np.log(np.abs(cv2.magnitude(dst_center[:, :, 0], dst_center[:, :, 1])))

# 显示图像
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.subplot(122)
plt.axis("off")
plt.imshow(result, cmap="gray")
plt.show()


2.2 OpenCV实现逆傅里叶变换

OpenCV API

dst= cv2.idft(src)

参数:

src:经过傅里叶变换后的图片
其他函数:

(同 【一、OpenCV实现傅里叶变换】)

【代码编写】

# %%opencv实现逆傅里叶变换
# 以灰度形式读入
img = cv2.imread('img\qiqiqi.png', 0)

# 使用cv2.dft()进行傅里叶变换
dst = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)

# 将变换后图像的低频部分转移到图像的中心
dst_center = np.fft.fftshift(dst)

#
# 中间可以定义相应的掩膜去留高频或者低频部分
#

# 使用np.fft.ifftshift将低频移动到原来的位置
dst_origin = np.fft.ifftshift(dst_center)

# 使用cv2.idft进行傅里叶的逆变化
img_idft = cv2.idft(dst_origin)

# 使用cv2.magnitude转化为空间域内
img_idft = cv2.magnitude(img_idft[:, :, 0], img_idft[:, :, 1])

# 显示图像
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.title('原图')
plt.subplot(122)
plt.axis("off")
plt.imshow(img_idft, cmap=plt.cm.gray)
plt.title('逆傅里叶变换')
plt.show()


2.3 Numpy实现傅里叶变换

Numpy

np.fft.fft2(img)

参数:

img:输入的灰度图像
其他函数:

(可参照 【一、OpenCV实现傅里叶变换】)

【代码编写】

# %%NumPy实现傅里叶变换
img = cv2.imread('img//qiqiqi.png', 0)

# 使用Numpy进行傅里叶变换
f = np.fft.fft2(img)

# 无处理(未把零频率分量移到中间)
mid_result = 20 * np.log(np.abs(f))

# 把零频率分量移到中间
fshift = np.fft.fftshift(f)
result = 20 * np.log(np.abs(fshift))

# 显示图像
plt.subplot(131)
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.title('原图')
plt.subplot(132)
plt.axis("off")
plt.imshow(mid_result, cmap=plt.cm.gray)
plt.title('Numpy傅里叶变换\n(未把零频率分量移到中心)')
plt.subplot(133)
plt.axis("off")
plt.imshow(result, cmap=plt.cm.gray)
plt.title('Numpy傅里叶变换\n(把零频率分量移到中心)')
plt.tight_layout()
plt.show()


2.4、Numpy实现逆傅里叶变换

Numpy

np.fft.ifft2(img)

参数:

img:经过傅里叶变换后的图像
【代码编写】

# %%Numpy实现逆傅里叶变换
img = cv2.imread('img//qiqiqi.png', 0)

# 进行傅里叶变换
f = np.fft.fft2(img)

# 逆傅里叶变换
f_center = np.fft.ifftshift(f)
f_origin = np.fft.ifft2(f_center)

# 设置区间
f_origin = np.abs(f_origin)

# 显示图像
plt.subplot(121)
plt.imshow(img, cmap="gray")
plt.axis("off")
plt.title('原图')
plt.subplot(122)
plt.axis("off")
plt.imshow(f_origin, cmap=plt.cm.gray)
plt.title('Numpy逆傅里叶变换')
plt.show()


 

三、应用实践:低通滤波与高通滤波

3.1 低通滤波:滤除高频分量 ——模糊图像(使用OpenCV)

滤除突变的高频信号,留下渐变的低频信号。

【代码编写】

# %%OpenCV低通滤波
img = cv2.imread('img//qiqiqi.png', 0)

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

# 定义掩模:生成的掩模中间为1周围为0
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2)  # 求得图像的中心点位置
mask = np.zeros((img.shape[0], img.shape[1], 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1

# 将掩模与傅里叶变化后图像相乘,保留中间部分
mask_img = dft_center * mask

img_idf = np.fft.ifftshift(mask_img)
img_idf = cv2.idft(img_idf)
img_idf = cv2.magnitude(img_idf[:, :, 0], img_idf[:, :, 1])

plt.subplot(121)
plt.axis('off')
plt.imshow(img, cmap='gray')
plt.subplot(122)
plt.axis('off')
plt.imshow(img_idf, cmap='gray')
plt.show()

3.2 高通滤波  ——滤除低频分量 - 锐化图像(使用OpenCV)

去除低频的底噪和低频轮廓信号,留下突变的高频信号

【代码编写】

将低通滤波的定义的掩膜由 中间0周围1 改为 中间1周围0

复制 
# 定义掩模:生成的掩模中间为0周围为1
crow, ccol = int(img.shape[0] / 2), int(img.shape[1] / 2) # 求得图像的中心点位置
mask = np.ones((img.shape[0], img.shape[1], 2), np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 0

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Redis的内存淘汰策略-volatile-ttl
  • 【Python机器学习】词向量推理——语义查询与类比
  • HarmonyOS实战开发:NAPI接口规范开发
  • 华为 HCIP-Datacom H12-821 题库 (3)
  • vscode Git代码版本回退
  • 【生日视频制作】宝马提车交车仪式感广告展示牌AE模板修改文字软件生成器教程特效素材【AE模板】
  • javacv-ffmpeg ProcessBuilder批量旋转图片
  • Elasticsearch Suggesters API详解与联想词自动补全应用
  • Oracle rac模式下undo表空间爆满的解决
  • 公钥密码选择题
  • Cesium 台湾省白膜数据渲染
  • Java语言程序设计基础篇_编程练习题**17.17(BitOutputStream)
  • IBM退出中国,LabVIEW未来走向何方?
  • PostgreSQL技术内幕6:PostgreSQL索引技术
  • uniapp / uniapp x UI 组件库推荐大全
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • Java编程基础24——递归练习
  • React16时代,该用什么姿势写 React ?
  • text-decoration与color属性
  • 飞驰在Mesos的涡轮引擎上
  • 聊聊flink的BlobWriter
  • 前端之React实战:创建跨平台的项目架构
  • 我与Jetbrains的这些年
  • 白色的风信子
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • C# - 为值类型重定义相等性
  • 大数据全解:定义、价值及挑战
  • 交换综合实验一
  • # Redis 入门到精通(一)数据类型(4)
  • #nginx配置案例
  • $nextTick的使用场景介绍
  • (ctrl.obj) : error LNK2038: 检测到“RuntimeLibrary”的不匹配项: 值“MDd_DynamicDebug”不匹配值“
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (NSDate) 时间 (time )比较
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (附源码)php投票系统 毕业设计 121500
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (十)Flink Table API 和 SQL 基本概念
  • (新)网络工程师考点串讲与真题详解
  • (译) 函数式 JS #1:简介
  • (转)程序员疫苗:代码注入
  • .gitignore文件—git忽略文件
  • .JPG图片,各种压缩率下的文件尺寸
  • .Net 中Partitioner static与dynamic的性能对比
  • .Net(C#)常用转换byte转uint32、byte转float等
  • .NET编程C#线程之旅:十种开启线程的方式以及各自使用场景和优缺点
  • .NET建议使用的大小写命名原则
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • /*在DataTable中更新、删除数据*/
  • /tmp目录下出现system-private文件夹解决方法
  • /var/lib/dpkg/lock 锁定问题
  • []sim300 GPRS数据收发程序
  • [000-01-018].第3节:Linux环境下ElasticSearch环境搭建
  • [2013AAA]On a fractional nonlinear hyperbolic equation arising from relative theory
  • [2544]最短路 (两种算法)(HDU)