图像的傅里叶变换

目录

​编辑

傅里叶基础

傅里叶基础numpy实现

逆傅里叶numpy实现

频域的高通滤波

傅里叶OpenCV实现

傅里叶OpenCV逆变换实现

频域的低通滤波

傅里叶变换有什么应用场景

傅里叶变换matlab实现


傅里叶基础

法国数学家吉恩·巴普提斯特·约瑟夫·傅里叶被世人铭记的最大的贡献是:他指出任何周期函数都可以表示为不同频率的正弦和/或余弦之和的形式,每个正弦项和/或余弦项乘以不同的系数(现在称该和为傅里叶级数)。无论函数多么复杂,只要它是周期的,并且满足某些适度的数学条件,都可以用这样的和来表示。即一个复杂的函数可以表示为简单的正弦和余弦之和。甚至非周期函数(单该曲线下的面积是有限的)也可以用正弦和/或许·余弦乘以加权函数的积分来表示。在这种情况下的公式就是傅里叶公式。

比如说我们以制作一个饮料的过程,使用时域的角度来看就是这样:

这里是什么意思呢,就是说一个饮料的制作需要在18点整放1个单位冰糖、3个单位红豆、2个单位的绿豆、4个单位的西红柿,还有1个单位的纯净水。然后再18:01分只需要假如一个单位的纯净水。后面也是一致。
而频域是怎么描述这件事的呢?

具体来说就是说他发现了一个规律,就是说这个制作过程,每分钟都要加入冰糖,每两分钟都要加入红豆,每三分钟都要加入一次绿豆…。
对于时域角度我们这样描述。

对于频域角度我们这样描述这件事,用直方图表示就是:

如果要考虑更精准的时间精度,我们就要引入相位这个概念。他是一个和时间差有关的一个表述。

这里我们说明一下就是时域和频域的表述是互逆的,对于时域我们是时间为横坐标,振幅为纵坐标。对于频域我们以频率为横坐标,振幅为纵坐标。但是可以看得出来频域的表述更加简单,但是比较抽象,不容易理解。
傅里叶说:任何连续周期信号,可以由一组适当的正弦曲线组合而成。
注意这里是一组而不是一个。比如对于这样的一个图像:
f(x)=3np.sin(0.8x)+7np.sin(1/3x)+2np.sin(0.2x)

看上去是毫无规律可言吧,但是它也可以由一组正弦函数组成。

他们是可逆的,想不到吧,乱七八糟的东西也有规律了。但是他们就是这样组合而成的吗?不可能吧,所以这里就是不是同时开始的一组余弦函数,在叠加时要体现开始的时间。也就说组合的函数他们的开始时间是不一样的。在这里分别对应0,2,3.看公式就看出来啦。
这里多说一嘴就是说傅里叶变换从时域角度来看,这个世界是动态的!从频域角度来看这个世界是静止的。
从数学角度来讲:傅里叶变换将一个任意的周期函数分解成为无穷个正弦函数的和的形式。
从物理角度来讲:傅里叶变换实现了将信号从空间域到频率域的转换。

傅里叶基础numpy实现

python是可以实现傅里叶变换的,这里就要说到三剑客的numpy了。对应的函数是:numpy.fft.fft2返回一个复数数组(complex ndarray)。numpy.fft.fftshift这个函数时表示把将零频率分量移到频谱中心。

还要设置频谱的范围20*np.log(np.abs(fshift)),对于图像来说就是255了。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('image\\lena.bmp',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
result = 20*np.log(np.abs(fshift))
plt.subplot(121)
plt.imshow(img, cmap = 'gray')
plt.title('original')
plt.axis('off')
plt.subplot(122)
plt.imshow(result, cmap = 'gray')
plt.title('result')
plt.axis('off')
plt.show()

结果是:

原图和频谱图像。

  • 傅里叶得到低频、高频信息,针对低频、高频处理能够实现不同的 目的。
  • 傅里叶过程是可逆的,图像经过傅里叶变换、逆傅里叶变换后,能 够恢复到原始图像
  • 在频域对图像进行处理,在频域的处理会反映在逆变换图像上

逆傅里叶numpy实现

对于傅里叶的逆操作这里没有什么可说的,就是把频域图像转回原图像。

函数是:numpy.fft.ifft2,那么还有一个操作就是把中间移动回去对啊。numpy.fft.ifftshiftiimg = np.abs(逆傅里叶变换结果)而第二个图就表示低频部分,边缘就表示为高频部分。

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('image\\boat.bmp',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('iimg'),plt.axis('off')
plt.show()

首先我们要进行傅里叶变换吧,才可以进行逆操作。结果是:

完全一致!!!

频域的高通滤波

首先我们来看看到底什么是高频,什么是低频在图像中如何理解。
低频对应图像内变化缓慢的灰度分量。例如,在一幅大草原的图像中,低频对应着广袤的颜色趋于一致的草原。
高频对应图像内变化越来越快的灰度分量,是由灰度的尖锐过渡造成的。例如,在一幅大草原的图像中,其中狮子的边缘等信息。
对于滤波我们之前也了解过了,就是说过滤掉不需要的部分呗。
通过低频的滤波器称为低通滤波器。
通过高频的滤波器称为高通滤波器
修改傅里叶变换以达到特殊目的,然后计算IDFT返回到图像域。比如我们可以利用傅里叶变换进行,图像增强、图像去噪、边缘检测、特征提取、图像压缩、图像加密等。
衰减高频而通过低频,低通滤波器,将模糊一幅图像。
衰减低频而通过高频,高通滤波器,将增强尖锐的细节,但是会导致图像
的对比度降低
那么我们只需要再滤波中来一个掩膜操作,具体看下面:

对于这个掩膜我们这样做:

rows, cols = img.shape
crow,ccol = int(rows/2) , int(cols/2)
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0

具体代码是:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('image\\boat.bmp',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
rows, cols = img.shape
crow,ccol = int(rows/2) , int(cols/2)
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(iimg, cmap = 'gray')
plt.title('iimg'),plt.axis('off')
plt.show()

得到后的图象是这样的:

可以出来把边缘描绘的非常完整,但是图像的对比度降低了。

傅里叶OpenCV实现

对于OpenCV中的傅里叶变换函数是:返回结果=cv2.dft(原始图像,转换标识)
返回结果是双通道的,第一个是实数部分,第二个通道是虚数部分。
输入图像要首先转换成np.float32 格式, np.float32(img)
flags = cv2.DFT_COMPLEX_OUTPUT,输出一个复数阵列
移动频谱部分和numpy一致,是这样的,numpy.fft.fftshift,然后进行返回值=cv2.magnitude(参数1,参数2)这里参数1就是实数部分,参数2就是虚数部分,并且进行𝑑𝑠𝑡 𝐼 = 根号𝑥(𝐼)2 + 𝑦(𝐼)2操作。
 

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('image\\lena.bmp',0)
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
result = 20*np.log(cv2.magnitude(dftShift[:,:,0],dftShift[:,:,1]))
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'),plt.axis('off')
plt.subplot(122),plt.imshow(result, cmap = 'gray')
plt.title('result'), plt.axis('off')
plt.show()

得到的图像和numpy一致。

傅里叶OpenCV逆变换实现

对于傅里叶变换的逆操作,使用OpenCV的函数就是返回结果=cv2.idft(原始数据),然后计算幅度函数仍然是返回值=cv2.magnitude(参数1,参数2)numpy.fft.ifftshift.

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('image\\lena.bmp',0)
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
ishift = np.fft.ifftshift(dftShift)
iImg = cv2.idft(ishift)
iImg= cv2.magnitude(iImg[:,:,0],iImg[:,:,1])
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'), plt.axis('off')
plt.subplot(122),plt.imshow(iImg, cmap = 'gray')
plt.title('inverse'), plt.axis('off')
plt.show()

频域的低通滤波

我们这里的想法就是:

自己构建一个低通滤波器,把中间位置设置成255,其余部分为0.那么我们做一个与操作,就可以把高频过滤了。

rows, cols = img.shape
crow,ccol = int(rows/2) , int(cols/2)
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1

低通滤波器构建代码。
然后我们完整代码就是:

import numpy as np
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('image\\lena.bmp',0)
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
rows, cols = img.shape
crow,ccol = int(rows/2) , int(cols/2)
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
fShift = dftShift*mask
ishift = np.fft.ifftshift(fShift)
iImg = cv2.idft(ishift)
iImg= cv2.magnitude(iImg[:,:,0],iImg[:,:,1])
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('original'), plt.axis('off')
plt.subplot(122),plt.imshow(iImg, cmap = 'gray')
plt.title('inverse'), plt.axis('off')
plt.show()

傅里叶变换有什么应用场景

傅里叶变换可以将一个时域信号转换成在不同频率下对应的振幅及相位,其频谱就是时域信号在频域下的表现,而反傅里叶变换可以将频谱再转换回时域的信号。最简单最直接的应用就是时频域转换,比如在移动通信的LTE系统中,要把接收的信号从时域变成频域,就需要使用FFT(快速傅里叶变换)。又例如对一个采集到的声音做傅立叶变化就能分出好几个频率的信号。比如南非世界杯时,南非人吹的呜呜主拉的声音太吵了,那么对现场的音频做傅立叶变化(当然是对声音的数据做),会得到一个展开式,然后找出呜呜主拉的特征频率,去掉展开式中的那个频率的sin函数,再还原数据,就得到了没有呜呜主拉的嗡嗡声的现场声音。而对图片的数据做傅立叶,然后增大高频信号的系数就可以提高图像的对比度。同样,相机自动对焦就是通过找图像的高频分量最大的时候,就是对好了。

傅里叶变换matlab实现

[i,lcmp]=imread('F:/123.jpg');%=======读取图像 显示图像
subplot(2,2,1),imshow(i,lcmp);
title('original');
ii=im2double(i); %=====将图像矩阵类型转换为double(图像计算很多是不能用整型的),没有这个会报错!! ,如果不用这个就必须转化为灰度图!
i1 = fft2(ii); %======傅里叶变换
i2 =fftshift(i1); %======将变换的频率图像四角移动到中心(原来良的部分在四角 现在移动中心,便于后面的处理)
i3=log(abs(i2)); %=====显示中心低频部分,加对数是为了更好的显示
subplot(2,2,2),imshow(i3,[]);
title('Fourier');
map=colormap(lcmp); %===取色谱
imwrite(i3,map,'f:/ffttank.bmp'); %===将上面i3输入到ffttank文件中
i5 = real(ifft2(ifftshift(i2))); %===频域的图反变换到空域 并取实部
i6 = im2uint8(mat2gray(i5)); %===取其灰度图
imwrite(i6,map,'f:/tank2.bmp','bmp'); %===利用灰度图和原来取得颜色模板 还原图像
subplot(2,2,3),imshow(i6);
title('anti-Fourier');
i7=rgb2gray(i);
i8=fft2(i7);%===对灰色图才能归一化。因为那是2维矩阵,彩色图是3维矩阵,需要转化为2维灰图
m=fftshift(i8); %直流分量移到频谱中心
%RR=real(m); %取傅立叶变换的实部
%II=imag(m); %取傅立叶变换的虚部
A=abs(m);%计算频谱幅值
%A=sqrt(RR.^2+II.^2);
A=(A-min(min(A)))/(max(max(A))-min(min(A)))*225; %归一化
subplot(2,2,4),imshow(A); %显示原图像
colorbar; %显示图像的颜色条
title('FFT spectrum'); %图像命名

如果觉得博主的文章还不错或者您用得到的话,可以免费的关注一下博主,如果三连收藏支持就更好啦!这就是给予我最大的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/153376.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

llvm源码windows编译

1.克隆llvm源码: git clone --config core.autocrlf=false https://github.com/llvm/llvm-project.git 2.创建build文件夹并生成makefile 生成前置条件: cmake ,ninja,python3要先安装 cmake -S llvm -B build -G Ninja -DCMAKE_BUILD_TYPE=Release 生成成功 3.编译 进…

初刷leetcode题目(7)——数据结构与算法

😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️Take your time ! 😶‍🌫️😶‍🌫️😶‍🌫️😶‍🌫️…

UE 调整材质UV贴图长宽比例

首先,为什么要先减去0.5呢,因为缩放的贴图中心在0,0原点,以这个点缩放效果是这样: 它缩放的图案不会在正中间,因为是以0,0点进行缩放的 以这个图的箭头去缩放图片的,所以不能使得缩放后的图片放在正中心 那…

【机器学习】038_梯度消失、梯度爆炸

一、原因 神经网络梯度 假设现在有一个 层的神经网络,每层的输出为一个对输入作 变换的函数结果 用 来表示第 层的输出,那么有下列公式: 链式法则计算损失 关于某一层某个参数 的梯度: 注意到, 为向量&am…

NX二次开发UF_CAM_ask_post_template_name 函数介绍

文章作者:里海 来源网站:里海NX二次开发3000例专栏 UF_CAM_ask_post_template_name Defined in: uf_cam.h int UF_CAM_ask_post_template_name(const char * * post_template_filename ) overview 概述 This function provides the name of the file…

git 提交成了LFS格式,如何恢复

平常习惯使用sourceTree提交代码,某次打开时弹出了一个【是否要使用LFS提交】的确认弹窗,当时不知道LFS是什么就点了确认,后续提交时代码全变成了这个样子 因为是初始化的项目首次提交,将近四百个文件全被格式化成了这个样子&…

利用ETLCloud自动化流程实现业务系统数据快速同步至数仓

现代企业有不少都完成了数字化的转型,而还未转型的企业或商铺也有进行数字化转型的趋势,由此可见,数据已经成为企业决策的重要依据。企业需要先获取数据,将业务系统数据同步至数仓进行整合,然后再进行数据分析。为了更…

Vatee万腾外汇市场新力量:vatee科技决策力

在当今数字化时代,Vatee万腾崭露头角,以其强大的科技决策力进军外汇市场,成为该领域的新力量。这一新动向将不仅塑造外汇市场的未来,也展现Vatee科技决策力在金融领域的引领作用。 Vatee万腾带着先进的科技决策力进入外汇市场&…

Java格式化类Format

文章目录 Format介绍Format方法- format(格式化)- parseObject(解析) 格式化分类日期时间格式化1. DateFormat常用方法getInstancegetDateInstancegetTimeInstancegetDateTimeInstance 方法入参styleLocale 2. SimpleDateFormat常…

CentOS7安装Docker遇到的问题笔记

笔记/朱季谦 以下是笔者本人学习搭建docker过程当中记录的一些实践笔记,过程当中也遇到了一些坑,但都解决了,就此记录,留作以后再次搭建时可以直接参考。 一、首先,先检查CentOS版本,保证在CentOS7版本以…

2023食药物质产业发展大会12月在浙江绍兴隆重召开

为更好地推动食药物质行业高质量发展,推进食药物质相关产品的创新应用,促进行业科技进步,提高行业技术水平,中国生物发酵产业协会定于12月15-17日在浙江省绍兴市召开“2023食药物质产业发展大会暨中国生物发酵产业协会食药物质专业…

栈和队列知识点+例题

1.栈 1.1栈的概念及结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端成为栈顶,另一端成为栈底。遵守后进先出的原则(类似于弹夹) 压栈:栈的插入操…

一文讲明 网络调试助手的基本使用 NetAssist

我 | 在这里 🕵️ 读书 | 长沙 ⭐软件工程 ⭐ 本科 🏠 工作 | 广州 ⭐ Java 全栈开发(软件工程师) 🎃 爱好 | 研究技术、旅游、阅读、运动、喜欢流行歌曲 🏷️ 标签 | 男 自律狂人 目标明确 责任心强 ✈️公…

实战 - 在Linux上部署各类软件

前言 为什么学习各类软件在Linux上的部署 在前面,我们学习了许多的Linux命令和高级技巧,这些知识点比较零散,同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用,但是并没有一些具体的实操能够串联起来这些知…

Ubuntu18.04安装Moveit框架

简介 Moveit是一个由一系列移动操作的功能包组成的集成化开发平台,提供友好的GUI,是目前ROS社区中使用度排名前三的功能包,Moveit包含以下三大核心功能,并集成了大量的优秀算法接口: 运动学:KDL,Trac-IK,IKFast...路径规划:OMPL,CHMOP,SBPL..碰撞检测:FCL,PCD... 一、更新功…

全球地表水年度数据集JRC Yearly Water Classification History, v1.4数据集

简介: JRC Yearly Water Classification History, v1.4是一个对全球水资源进行分类的数据集,覆盖了1984年至2019年的时间范围。该数据集是由欧盟联合研究中心(JRC)开发的,使用的数据源是来自Landsat系列卫星的高分辨率…

十. Linux关机重启命令与Vim编辑的使用

关机重启命令 shutdown命令 其他关机命令 其他重启命令 系统运行级别 系统默认运行级别与查询 退出登录命令logout 文本编辑器Vim Vim简介 没有菜单,只有命令Vim工作模式 Vim常用命令 插入命令 定位命令 删除命令 复制和剪切命令 替换和取消命令 搜索和搜索替换命令 保存和退出…

毅速丨嫁接打印在模具制造中应用广泛

在模具行业中,3D打印随形水路已经被广泛认可,它可以提高冷却效率,从而提高产品良率。然而,全打印模具制造的成本相对较高,因为需要使用金属3D打印机和专用材料。为了节省打印成本,同时利用3D打印的优势&…

【Python】问题描述:输入A、B,输出A+B。样例输入12 45样例输出57

1、问题描述 输入A、B,输出AB。 样例输入 12 45 样例输出 57 nums list(map(int,input().split(" "))) print(sum(nums))

STM32 Flash

FLASH简介 Flash是常用的用于存储数据的半导体器件,它具有容量大,可重复擦写,按“扇区/块”擦除、掉电后数据可继续保存的特性。 常见的FLASH主要有NOR FLASH和NAND FLASH两种类型。NOR和NAND是两种数字门电路,可以简单地认为FL…