离散傅里叶变换DFT的应用
目录
一维DFT
1 DFT的相关内容
- 一维DFT的意义:一维信号由若干个不同频率的正余弦信号组合而成;
- 一维DFT的解决问题:确定输入信号中有多少个周期信号,以及周期信号的幅值、频率、相位值;
- 一维DFT的原理:
- 通过采样频率fs对原始信号进行离散化,依次计算离散信号与各个基信号的相关性(N为采样点数对应存在N个基信号,每个基信号与离散信号会有一个复数结果)

- 通过采样频率fs对原始信号进行离散化,依次计算离散信号与各个基信号的相关性(N为采样点数对应存在N个基信号,每个基信号与离散信号会有一个复数结果)
- 一维DFT的求取步骤:
- 设定采样频率fs,对输入信号f(t)进行采样,得到N个采样点,对应的离散化信号记作x[n],n = [0, 1, ..., N) ;
- 通过DFT公式计算得到N个匹配对X[k],k= [0, 1, ..., N),X[k]代表N个采样点的原始信号中存在着k个周期的的信号分量,即第k+1个基信号;
\[X[k]=Σ_{n=0}^{N-1} x(n){e^{-jA}}=Σ_{n=0}^{N-1} x(n)(cos(A)-jsin(A)), 其中A=2πkn/N.
\]- 根据 总的采样时长 = N / fs,故对于X[k]≠0时,对应输入信号的 频率 f = (k * fs) / N;在k≠0时,幅值为 复数X[k]的模 除以 (N/2),在k=0时,幅值为 复数X[k]的模 除以 N;相位即为 复数X[k]的幅角;
- 注:因为要满足采样定理 fs ≥ 2f,故只使用频率域的前一半结果,由 f = k*fs/N 可推导;
- 假设,X[2] 的模为不为0, 这说明N个采样点中有2个周期,故 每个周期的时长T =N / (2 ** fs) *,即输入信号的频率 f = (2 * fs) / N;
2 DFT计算结果验证
DFT计算公式:
\]
通过numpy中np.fft.fft() 函数 验证 自己实现的代码是正确的,代码如下
import cmath
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
np.set_printoptions(edgeitems=3)
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
N = len(arr)
omega = 2 * np.pi / N
mag_ls = []
for k in range(N):
mag_ls.append(sum([arr[j] * cmath.exp(complex(0, -j * omega * k)) for j in range(N)]))
print(np.array(mag_ls))
# [45. +0.j -4.5+12.364j -4.5 +5.363j -4.5 +2.598j -4.5 +0.793j
# -4.5 -0.793j -4.5 -2.598j -4.5 -5.363j -4.5-12.364j]
X = np.fft.fft(arr)
print(X)
# [45. +0.j -4.5+12.364j -4.5 +5.363j -4.5 +2.598j -4.5 +0.793j
# -4.5 -0.793j -4.5 -2.598j -4.5 -5.363j -4.5-12.364j]
3 DFT的时频曲线分析
问题:给定一个连续的输入信号 f(t) = 2 + 3 * np.cos(2 * np.pi * 0.2 * t) + 1.5 * np.cos(2 * np.pi * 0.1 * t) ,通过 DFT 来求解 输入信号中各个周期函数的幅值、频率、相位值;
思路:参考 一维DFT的求取步骤
代码实现:
import matplotlib.pyplot as plt
import numpy as np
fs = 0.5 # 采样频率 HZ
t = np.arange(0, 100, 1 / fs) # 时间序列,每隔 1/fs 秒采集一次数据,共采集N次
N = len(t) # 序列的长度
x = 2 + 3 * np.cos(2 * np.pi * 0.2 * t) + 1.5 * np.cos(2 * np.pi * 0.1 * t)
X = np.fft.fft(x)
m = np.abs(X)
Mag = m.copy()
ifft_x = np.fft.ifft(X)
ifft_m = np.abs(ifft_x)
freq = [k * fs / N for k in range(N)]
m[0] /= N
m[1:] /= (N / 2)
print("freq:", freq)
plt.figure()
name = "f(t) = 2 + 3 * cos(2π * 0.2 * t) + 1.5 * np.cos(2π * 0.1 * t)"
plt.subplot(131), plt.plot(t, x, c="b", marker="o")
plt.title(name), plt.xlabel("采样周期 t={} 秒".format(1/fs)), plt.ylabel("输出f(t)")
plt.subplot(132), plt.plot(range(N), Mag, c="g", marker="o"), plt.title("DFT 结果")
plt.title("DFT 结果"), plt.xlabel("基信号N=[0~{})".format(N)), plt.ylabel("基信号对应的幅值")
plt.subplot(133), plt.plot(freq, m, c="r", marker="o"), plt.title("DFT 结果")
plt.title("DFT 结果"), plt.xlabel("信号的频率".format(N)), plt.ylabel("真实幅值")
plt.figure()
plt.subplot(121), plt.plot(t, x, c="b"), plt.title("原始信号")
plt.subplot(122), plt.plot(t, ifft_m, c="g"), plt.title("逆DFT信号")
plt.show()
输出结果:


由图1可知:
- fs=0.5hz,采样点 N = 50, f = k * fs / N, 直流分量的幅值 = X[0] 模 / (50),其它分量的幅值 = X[k] 模 / (25) k≠0
- X[0] 对应输入信号中2,
- X[10] 对应输入信号中 1.5 * np.cos(2 * np.pi * 0.1 * t) ,
- X[20] 对应输入信号中 3 * np.cos(2 * np.pi * 0.2 * t)
由图2可知,DFT与IDFT是可逆的
4 DFT的应用
方法:使用DFT求取图像中单个网格的像素大小, psx = 用图像的宽度 除以 x方向上网格的数量,psx = 用图像的高度 除以 y方向上网格的数量;
思路:求解psx — 在x方向上求取图像的像素均值,然后经过DFT变换,得到频域上的周期信号,其中周期个数即为网格数量;为了缩小误差,可以按照一定大小来缩小图像,重复psx 求取过程,通过平均值来提高计算精度;同理 psy一样。
运行结果:



二维DFT
1 DFT在图像处理时的相关内容
- 图像中高频与低频区别:
- 高频:变化剧烈的灰度分量,例如边界
- 低频:变化缓慢的灰度分量,例如一片大海
- 傅里叶变换的作用:滤波、图像配准;
- 低通滤波器:只保留低频,会使得图像模糊
- 高通滤波器:只保留高频,会使得图像细节增强
2 DFT滤波应用
import cv2
import numpy as np
from matplotlib import pyplot as plt
def DFT(image, isshow=True):
img_float32 = np.float32(image)
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
# 得到灰度图能表示的形式
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
if isshow:
plt.subplot(121), plt.imshow(image, 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()
return dft_shift
def IDFT(image, dft_shift, Filtter="None", isshow=True):
if Filtter:
rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2) # 中心位置
mask = None
if Filtter == "HIGH":
# 高通滤波
mask = np.ones((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 0
elif Filtter == "LOW":
# 低通滤波
mask = np.zeros((rows, cols, 2), np.uint8)
mask[crow - 30:crow + 30, ccol - 30:ccol + 30] = 1
dft_shift = dft_shift * mask
f_ishift = np.fft.ifftshift(dft_shift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])
if isshow:
plt.subplot(121), plt.imshow(image, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img_back, cmap='gray')
plt.title('Result'), plt.xticks([]), plt.yticks([])
plt.show()
return img_back
if __name__ == "__main__":
img = cv2.imread('lena.jpg', 0)
fshift = DFT(img)
IDFT(img, fshift, Filtter="LOW")
运行结果:



离散傅里叶变换DFT的应用的更多相关文章
- 灰度图像--频域滤波 傅里叶变换之离散傅里叶变换(DFT)
学习DIP第23天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不 ...
- 【转】离散傅里叶变换-DFT(FFT)基础
转:https://blog.csdn.net/zhangxz259/article/details/81627341 什么是离散傅里叶变换 matlab例子 本文是从最基础的知识开始讲解,力求用最通 ...
- 离散傅里叶变换DFT入门
网上对于傅里叶变换相关的文章很多(足够多),有的是从物理相关角度入场,有的从数学分析角度入场.对于有志学习相关概念的同学还是能够很好的理解的. 数学包括三大块:代数学.几何.数学分析.前两块我们在中学 ...
- 用matlab脚本语言写M文件函数时用三种方法简单实现实现DFT(离散傅里叶变换)
%用二重循环实现DFT: function xk=dt_0(xn); %define a function N=length(xn); %caculate the length of the vari ...
- c语言数字图像处理(六):二维离散傅里叶变换
基础知识 复数表示 C = R + jI 极坐标:C = |C|(cosθ + jsinθ) 欧拉公式:C = |C|ejθ 有关更多的时域与复频域的知识可以学习复变函数与积分变换,本篇文章只给出DF ...
- opencv 3 core组件进阶(3 离散傅里叶变换;输入输出XML和YAML文件)
离散傅里叶变换 #include "opencv2/core/core.hpp" #include "opencv2/imgproc/imgproc.hpp" ...
- OpenCV离散傅里叶变换
离散傅里叶变换 作用:得到图像中几何结构信息 结论:傅里叶变换后的白色部分(即幅度较大的低频部分),表示的是图像中慢变化的特性,或者说是灰度变化缓慢的特性(低频部分). 傅里叶变换后的黑色部分(即幅度 ...
- 离散傅里叶变换(DFT)
目录 一.研究的意义 二.DFT的定义 三.DFT与傅里叶变换和Z变换的关系 四.DFT的周期性 五.matlab实验 五.1 程序 ...
- Opencv 实现图像的离散傅里叶变换(DFT)、卷积运算(相关滤波)
我是做Tracking 的,对于速度要求非常高.发现傅里叶变换能够使用. 于是学习之. 核心: 最根本的一点就是将时域内的信号转移到频域里面.这样时域里的卷积能够转换为频域内的乘积! 在分析图像信号的 ...
- 【算法•日更•第四十二期】离散傅里叶变换(DFT)
▎前言 小编相当的菜,这篇博客难度稍高,所以有些可能不会带有证明,博客中更多的是定义. 我们将要学到的东西: 复数 暴力多项式乘法 DFT 当然,小编之前就已经写过一篇博客了,主要讲的就是基础多项式, ...
随机推荐
- 多重断言插件之pytest-assume的简单使用
背景: pytest-assume是Pytest框架的一个扩展,它允许在单个测试用例中多次断言.通常情况下,当一个断言失败时,测试会立即停止执行,而pytest-assume允许我 们继续执行剩余的断 ...
- Python 基础面试第三弹
1. 获取当前目录下所有文件名 import os def get_all_files(directory): file_list = [] # os.walk返回一个生成器,每次迭代时返回当前目录路 ...
- CodeForces 1324F Maximum White Subtree
题意 给定一棵\(n\)个节点的无根树,每个节点为黑色或者白色,每个点的答案为包含该点的子树(指无根子树)的白色节点数减黑色节点数的最大值 分析 对于无根树的题一般指定某一个点为根,不妨设为\(1\) ...
- 使用GPU训练Pytorch模型
如何使用GPU训练Pytorch模型 这两天的深度学习实验真实让人头疼,传说中的"猫狗大战",对模型的训练用CPU的话9h起步,12h是常态,大学生哪耗得起,因此查找资料搭建了GP ...
- 【matplotlib基础】--结合地图
如果分析的数据与地域相关,那么,把分析结果结合地图一起展示的话,会让可视化的效果得到极大的提升. 比如,分析各省GDP数据,人口数据,用柱状图,饼图之类的虽然都可以展示分析结果,不过,如果能在全国的地 ...
- Forest轻量级框架的声明式使用
1.Forest框架声明式接口的基础使用 1.1构建接口 在 Forest 中,所有的 HTTP 请求信息都要绑定到某一个接口的方法上,不需要编写具体的代码去发送请求.请求发送方通过调用事先定义好 ...
- 《流畅的Python》 读书笔记 230926(第一章后半部分)
1.2 如何使用特殊方法 特殊方法的存在是为了被 Python 解释器调用的,你自己并不需要调用它们 就是说通常你都应该用len(obj)而不是obj.__len()__,无论是系统预置的,还是你自己 ...
- vscode编写markdown
1. 需求分析 2. 环境搭建 1. 需求分析 最近在网上折腾了好久Markdown的写作环境,作为一个普通用户,总结一下个人对于Markdown写作环境的几点需求.由于本人刚接触Markdown不久 ...
- C#使用iKvm黑科技无缝接入JVM生态
前言 时间过得飞快,一转眼国庆假期也要过去了,再不更新博客就太咸鱼了-- 最近在开发AIHub的时候想找个C#能用的命名实体识别库,但一直没找到,AI生态方面C#确实不太丰富,这块还是得Python, ...
- BS系统的登录鉴权流程演变
1 基础知识 用户登录是使用指定用户名和密码登录到系统,以对用户的私密数据进行访问和操作.在一个有登录鉴权的BS系统中,通常用户访问数据时,后端拦截请求,对用户进行鉴权,以验证用户身份和权限.用户名. ...