【数字图像处理笔记】Matlab实现离散傅立叶变换 (二)

news2025/1/16 13:54:02

请添加图片描述

  • 💌 所属专栏:【数字图像处理笔记】

  • 😀 作  者:我是夜阑的狗🐶

  • 🚀 个人简介:一个正在努力学技术的CV工程师,专注基础和实战分享 ,欢迎咨询!

  • 💖 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信 😘 😘 😘

您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!🤩 🤩 🤩

请添加图片描述

文章目录

  • 前言
  • 一、原理
  • 二、实现过程
      • 1、离散傅立叶变换(直接调用Matlab内置函数):
      • 2、离散傅立叶变换(自己编写):
      • 3、离散傅里叶逆变换(自己编写):
  • 总结


前言

  大家好,又见面了,我是夜阑的狗🐶,本文是专栏【数字图像处理笔记】专栏的第2篇文章;
  这是今天学习到数字图像处理笔记 – Matlab实现离散傅立叶变换 💖💖💖,开启新的征程,记录最美好的时刻🎉,每天进步一点点。
  专栏地址:【数字图像处理笔记】 , 此专栏是我是夜阑的狗对数字图像处理学习过程的总结,希望能够加深自己的印象,以及帮助到其他的小伙伴😉😉。
  如果文章有什么需要改进的地方还请大佬不吝赐教👏👏。

一、原理

  要在数字图像处理中应用傅立叶变换, 还需要解决两个问题:

  • 问题一:在数学中进行傅立叶变换的f(x)为连续(模拟)信号, 而计算机处理的是数字信号(图像数据);
  • 问题二:数学上采用无穷大概念,而计算机只能进行有限次计算。

  通常, 将受这种限制的傅立叶变换称为离散傅立叶变换(Discrete Fourier Transform,DFT)。离散傅立叶变换的定义如下。

  • 离散傅立叶正变换:

F ( u ) = ∑ x = 0 N − 1 f ( x ) e − j 2 π u x N F(u) = \sum_{ \begin{subarray}{l} x=0 \end{subarray}}^{N-1}f(x)e^{-j{\frac {2 \pi ux} N}} F(u)=x=0N1f(x)ejN2πux
  其中 u = 0 , 1 , 2 , Λ , N − 1 u = 0,1,2,\Lambda, N-1 u=0,1,2,Λ,N1

  • 离散傅立叶逆变换:

f ( u ) = 1 N ∑ u = 0 N − 1 F ( x ) e − j 2 π u x N f(u) = {\frac 1 N}\sum_{ \begin{subarray}{l} u=0 \end{subarray}}^{N-1}F(x)e^{-j{\frac {2 \pi ux} N}} f(u)=N1u=0N1F(x)ejN2πux
  其中 x = 0 , 1 , 2 , Λ , N − 1 x = 0,1,2,\Lambda, N-1 x=0,1,2,Λ,N1

二、实现过程

1、离散傅立叶变换(直接调用Matlab内置函数):

  代码:

I=imread('cameraman.tif');
% I=rgb2gray(I);	%将图像转换为灰度图
I=im2double(I);     %将图像的数据格式转换为double型的 
F=fft2(I);               %傅立叶变换
%不进行象限转换
F1=abs(F);             %傅里叶变换的模
T1=log(F1+1);		 %数据范围压缩
%进行象限转换
F=fftshift(F);          %对傅里叶变换后的图像进行象限转换
F=abs(F);               %傅里叶变换的模
T=log(F+1);           %数据范围压缩
figure;                    %显示
subplot(2,2,1);imshow(I);
subplot(2,2,2);imshow(I);
subplot(2,2,3);imshow(T,[]); 
subplot(2,2,4);imshow(T1,[]);

  运行结果如下图所示:

在这里插入图片描述

  从图中可以看出,原图像经过快速傅立叶变换 fft 后可以得到频谱图;以及通过 ffshift 函数将零频点移到频谱的中间,可以更直观观察傅立叶变换,傅立叶变换能使从空间域与频率域两个不同角度来分析图像问题。还可以通过 ifftshift 函数从频率域反映射到空间域,傅里叶逆变换基本还原图像。
  在进行傅立叶变换的具体实现中,要注意对fft变换后的频域矩阵数值比较大,一般采用log(abs[F]+1) 来对缩放频域,保证映射都在正数范围内,abs 函数可以求出复数矩阵的模缩放处理后进行显示。
  频谱图表示信号变化的快慢剧烈程度,通过分析不同图像和频谱图的关系时发现,高频信号对应图像的边缘细节,低频信号对应图像的大致概貌和轮廓。因此,对于细节边缘清晰或者噪声较多的图像,经过傅立叶变换后,靠外边的高频信号更多;而对于平滑、具备大体轮廓的图像,经过傅立叶变换后,靠中间的低频信号更多。
  所以,频谱图中的四个角和X,Y轴的尽头都是高频。可以以发现频谱图中的较亮白线应该是对应相机三脚架的边缘以及衣服的边缘。

2、离散傅立叶变换(自己编写):

  代码:

clc; clear;

data = imread('cameraman.tif');  % 数据——最好比卷积核的尺寸大
data = im2double(data); 
% data = rgb2gray(data);     % rgb转为灰度图像
subplot(1,3,1);
imshow(data);
title('原始图像')

zidai = fft2(data);   % matlab自带函数,来用对比
T1= abs(zidai);    %傅里叶变换的模
T1= fftshift(T1);   %对傅里叶变换后的图像进行象限转换
T1 = log(T1+1);	  %数据范围压缩
subplot(1,3,2);
% imshow(real(zidai));  % 一般只要实部
imshow(T1,[]); 
title('fft2');

size_data = size(data);
M = size_data(1);  % 图(原始数据矩阵)的长
N = size_data(2);  % 图(原始数据矩阵)的宽

% 下面是傅里叶正变换必备的一些矩阵:
Wm = exp(-j*2*pi/M);
Wn = exp(-j*2*pi/N); % 不同G中用不同的W
Em = zeros(M);
En = zeros(N);     % E是辅助计算矩阵
Gm = zeros(M)+Wm;
Gn = zeros(N)+Wn;  % G是计算时要用的矩阵
F = zeros(M,N);    % F是转换到频域的结果

% 对Gm的计算: 循环长度为M
fprintf('二维离散傅里叶变换开始:\n');
for row = 0:M-1
    for col = 0:M-1
        Em(row+1,col+1) = row * col;
        Gm(row+1,col+1) = Gm(row+1,col+1)^Em(row+1,col+1);
    end
end
% 对Gn的计算: 循环长度为N
for row = 0:N-1
    for col = 0:N-1
        En(row+1,col+1) = row * col;
        Gn(row+1,col+1) = Gn(row+1,col+1)^En(row+1,col+1);
    end
end

% F = real(Gm*data*Gn);  % F = Gm*f*Gn是计算公式,一般只要实部
F = Gm*data*Gn;
subplot(1,3,3);
T=fftshift(F);   %对傅里叶变换后的图像进行象限转换
T=abs(T);        %傅里叶变换的模
T=log(T+0.7);  %数据范围压缩
% imshow(F);
imshow(T,[]);
title('myfft2');

error = sum(sum((real(F)-real(zidai)).^2));
if error < 10^(-10)
    fprintf('自带与手写结果一致!\n');
else
    fprintf('不一致!\n');
end

  运行结果如下图所示:

在这里插入图片描述

  从图中的对比结果可以看出,通过编程实现傅里叶变换与 Matlab 自带的傅里叶变换函数得到的频谱图基本一致,说明了该程序的正确性。

3、离散傅里叶逆变换(自己编写):

  代码:

% 鉴于正向fft2手写与自带结果一致;
% ifft2的输入就直接用自带的fft2的结果。
clc; clear;

data = imread('cameraman.tif');  % 数据——最好比卷积核的尺寸大
data = im2double(data); 
% data = rgb2gray(data);     % rgb转为灰度图像
subplot(1,3,1);
imshow(data);
title('原始图像')

F = fft2(data);
T1= abs(F);
T1= fftshift(T1);
T1 = log(T1+1);	
subplot(1,3,2);
imshow(T1,[]);
% imshow(real(F));  % 一般画图只要实部, 作为输入时实虚都要!!
title('fft2');

% s = ifft2(F);
% subplot(1,3,3);
% imshow(s);
% return;

size_data = size(F);
M = size_data(1);  % 图(原始数据矩阵)的长
N = size_data(2);  % 图(原始数据矩阵)的宽

% 下面是傅里叶逆变换必备的一些矩阵:
Wm = exp(-j*2*pi/M);
Wn = exp(-j*2*pi/N);  % 不同G中用不同的W
Em = zeros(M);
En = zeros(N);        % E是辅助计算矩阵
Gm = zeros(M)+Wm;
Gn = zeros(N)+Wn;  % G是计算时要用的矩阵
f = zeros(M,N);    % F是转换到频域的结果

% 对Gm的计算: 循环长度为M
fprintf('二维离散反傅里叶变换开始:\n');
for row = 0:M-1
    for col = 0:M-1
        Em(row+1,col+1) = -row * col;
        Gm(row+1,col+1) = Gm(row+1,col+1)^Em(row+1,col+1);
    end
end
Gm = Gm/M;
% 对Gn的计算: 循环长度为N
for row = 0:N-1
    for col = 0:N-1
        En(row+1,col+1) = -row * col;
        Gn(row+1,col+1) = Gn(row+1,col+1)^En(row+1,col+1);
    end
end
Gn = Gn/N;   % 注意:这个/N和上面的/M都是算完G之后才除以的!因为上面计算的时候是幂项变化!

f = real(Gm*F*Gn);  % f = Gm*F*Gn是计算公式,一般只要实部
subplot(1,3,3);
imshow(f);
title('逆变换myidft2');

error = sum(sum((real(f)-real(data)).^2));
if error < 10^(-10)
    fprintf('反变换后与原图一致!\n');
else
    fprintf('不一致!\n');
end

  运行结果如下图所示:

在这里插入图片描述

  从图中的傅里叶逆变换处理结果可以看出,通过编程实现的傅里叶逆变换得到图像与原图基本一致,说明了该程序的正确性。
  通过本次操作基本掌握傅立叶变换的基本原理和实现算法。在实际过程中遇到以下几个问题及解决方法:

  • (1)要傅里叶变换频谱图进行分析,频谱没有中心化。解决方法:调用 fftshift() 函数对频谱图进行中心化。

总结

  感谢观看,如果觉得有帮助,请给文章点个赞吧,让更多的人看到。🌹 🌹 🌹

在这里插入图片描述

  也欢迎你,关注我。👍 👍 👍

  原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!下期再见。🎉

更多专栏订阅:

  • 😀 【LeetCode题解(持续更新中)】
  • 🌼 【鸿蒙系统】
  • 👑 【Python脚本笔记】
  • 🚝 【Java Web项目构建过程】
  • 💛 【微信小程序开发教程】
  • 【JavaScript随手笔记】
  • 🤩 【大数据学习笔记(华为云)】
  • 🦄 【程序错误解决方法(建议收藏)】
  • 🚀 【软件安装教程】



订阅更多,你们将会看到更多的优质内容!!

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

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

相关文章

离线语音模块初步学习——LSYT201B(深圳雷龙发展)

一 、产品简介 首先简单介绍下该离线语音模块&#xff0c;官方给出的介绍是&#xff1a;YT2228 是根据智能语音交互市场需求及思必驰算法的发展方向定义开发的 “芯片算法”人工智能人机语音交互解决方案&#xff0c;具有高性能、低功耗等特点。该芯片通过软硬融合的方法&…

流量代理第一弹:入门使用

定义 “流量代理是一种网络通信技术&#xff0c;它充当网络通信的中间人&#xff0c;将流量从一个地方传递到另一个地方。通常用于实现网络隧道、网络加速、访问控制和隐私保护等功能。“ 上面是来自chatGPT的回答。从这个回答中&#xff0c;我们不难看出&#xff0c;流量代理…

专利视角下的量子竞赛:《2024全球专利格局白皮书》

2024年1月&#xff0c;欧洲量子产业联盟&#xff08;QuIC&#xff09;发布了题为《全球量子技术专利格局描述》的综合白皮书。 该文件以透明的视角展示了当今的知识产权格局&#xff0c;包括知识产权持有人的地理分布。该文件由 QuIC 知识产权&#xff08;IP&#xff09;与贸易…

【学习笔记】Python 使用 matplotlib 画图

文章目录 安装中文显示折线图、点线图柱状图、堆积柱状图坐标轴断点参考资料 本文将介绍如何使用 Python 的 matplotlib 库画图&#xff0c;记录一些常用的画图 demo 代码 安装 # 建议先切换到虚拟环境中 pip install matplotlib中文显示 新版的 matplotlib 已经支持字体回退…

Linux Docker下载镜像更改默认存储位置/usr/lib/docker

用于解决docker默认存储位置磁盘空间不足&#xff0c;切换存储位置 1、执行下面命令查看 现在docker的存储位置 docker info | grep "Docker Root Dir" 1.2、如果之前已经下载过镜像可以用mv命令把原来的镜像复制到新的地址 mv /var/lib/docker /data/docker 2、…

vue3中的ref、isRef、shallowRef、triggerRef和customRef

1.ref 接受一个参数值并返回一个响应式且可改变的 ref 对象。 ref 对象拥有一个指向内部值的单一属性 .value property &#xff0c;指向内部值。 例&#xff1a;此时&#xff0c;页面上的 str1 也跟着变化 <template><div><button click"handleClick&quo…

RK3588构建ubuntu22.04根文件系统

前言 RK系列的平台提供了buildroot和debian的系统&#xff0c;使用脚本可以直接构建出来&#xff0c;但是没有提供ubuntu的系统&#xff0c;很多厂商只提供一个rootfs.img的固件包&#xff0c;没有将方法开源出来。本文实现了从ubuntu官网开始构建一个ubuntu22.04根文件系统。…

python数字验证码自动识别

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在网络上&#xff0c;许多网站和应用程序使用验证码&#xff08;Completely Automated Publ…

Vue2 —— 学习(十一)

目录 一、路由 vue-router &#xff08;一&#xff09;路由与路由器 &#xff08;二&#xff09;vue-router 理解 &#xff08;三&#xff09;SPA 理解 &#xff08;四&#xff09;路由 理解 &#xff08;五&#xff09;小案例 1.About.vue 2.Home.vue 3.index.js 4…

移动端应用(APP)如何设计测试用例?

为 APP 设计测试用例需要考虑移动设备的特殊性&#xff0c;如不同的操作系统、设备尺寸、硬件特性以及应用程序自身的特定功能。 以下是为APP设计测试用例时要考虑的内容&#xff1a; 1. 理解需求 熟悉APP的功能需求、用户故事和设计文档。 确定APP的目标用户群体、使用场景…

12.Blender 界面介绍(上)及物体基础编辑操作

设置语言 首先在菜单栏打开编辑-Preferences-界面-翻译&#xff0c;可以修改语言 这里使用的是Steam上下载的4.1版本 工具栏 左边的工具栏&#xff0c;按T就会出现&#xff0c;再按T就会隐藏 右边的工具栏是按N&#xff0c;按N显示&#xff0c;再按N隐藏 旋转画面 长按鼠…

MySQL基础之单表操作(定义DDL,增删改DML,查DQL)

目录 一、概述1.1 什么是数据库1.2 连接MySQL1.3 数据模型1.4 SQL语句的分类1.5 数据类型 二、数据库设计-DDL2.1 数据库层面2.2 数据表层面创建表约束查询修改add,modify,change,drop,rename(表)删除 三、数据库操作-DML3.1 添加数据insert3.2 修改数据update3.3 删除数据dele…

做外贸与其质疑,不如脚踏实地做事

小莉说最近好多自媒体添加WhatsApp的客户都是非洲的&#xff0c;有些打电话过来都不想接&#xff0c;因为他们都是没钱的主&#xff0c;接着还截图了一个客户头像给我&#xff0c;很不耐烦地说&#xff1a;像这种抽烟的客户头像&#xff0c;一看就不是正经人&#xff0c;无论他…

土压力计:监测地下压力变化的必备工具

在土木工程、地质勘探和地下建筑等领域&#xff0c;地下土壤的力学特性对工程的稳定性和安全性起着至关重要的作用。而土压力计作为一种重要的监测设备&#xff0c;能够准确地测量地下土壤的压力变化&#xff0c;为工程设计和施工提供关键数据。本文将探讨土压力计的原理、应用…

CRAFT文字检测算法解析和基于C++和TensorRT的推理实现

本文讲解了CVPR 2019的一篇文字检测算法《Character Region Awareness for Text Detection》的原理&#xff0c;并给出我使用C和TensorRT重新实现的推理&#xff0c;速度比原版代码快12倍。 论文&#xff1a;https://arxiv.org/pdf/1904.01941.pdf 官方代码&#xff1a;https:…

echarts地图记录

小记录&#xff1a; 如果调整地图大小不管用的时候&#xff0c;看一下map的值是否为china 当值为china的时候&#xff0c;地图会加上“南海诸岛”部分&#xff0c;尝试修改map的值

Netfilter漏洞提权利用(CVE-2023-35001)

前言 Netfilter是一个用于Linux操作系统的网络数据包过滤框架&#xff0c;它提供了一种灵活的方式来管理网络数据包的流动。Netfilter允许系统管理员和开发人员控制数据包在Linux内核中的处理方式&#xff0c;以实现网络安全、网络地址转换&#xff08;Network Address Transl…

centos7搭建maven私服nexus

1.nexus Nexus Repository Manager&#xff08;通常简称 Nexus 或 Nexus RM&#xff09;是由Sonatype公司开发的一款开源的、强大的软件仓库管理工具&#xff0c;主要用于企业级的二进制组件&#xff08;如Java库、Node.js模块、Python包等&#xff09;存储、管理和分发。 官方…

定序器导出fbx到max里对位k动作

可以把场景移动到原点去k动作&#xff0c;然后可以恢复到ue4的位置 -- 定义全局变量 global CenterPoint undefined global averageCenter [0,0,0]-- 定义对话框 rollout restoreRollout "定序器>FBX>MAX" (button CreateButton "建立中心点" wid…

使用JS代理 实现大对象的功能拆解

序言 在Android开发中&#xff0c;可以通过webView的addJavascriptInterface方法注入一个对象到网页中。但是随着开发的需求越来越多。这个对象身上的方法也越来越多。这个对象对应的java类&#xff0c;体积越来越大&#xff0c;不利于维护。为了在不影响之前代码的基础上。把…