002 OpenCV dft 傅里叶变换

目录

一、傅里叶变换

1.1 傅里叶变换概念

1.2 opencv中傅里叶变换

二、实验代码

一、环境

本文使用环境为:

  • Windows10
  • Python 3.9.17
  • opencv-python 4.8.0.74

二、傅里叶变换

2.1 傅里叶变换概念

傅里叶变换(Fourier Transform)是一种在数学、物理和工程领域广泛应用的算法,用于分析信号或数据的频率成分。它是由法国数学家约瑟夫·傅里叶(Joseph Fourier)于19世纪初提出的,因此得名。傅里叶变换的基本思想是将一个时域信号转换为频域信号,或者将一个频域信号转换回时域信号。这种转换可以帮助我们更好地理解和分析信号的特性,例如幅度、频率和相位等。

傅里叶变换可以分为连续傅里叶变换(Continuous Fourier Transform,CFT)和离散傅里叶变换(Discrete Fourier Transform,DFT)。连续傅里叶变换用于处理连续时间信号,而离散傅里叶变换用于处理离散时间信号。在实际应用中,由于计算机处理的是离散数据,因此离散傅里叶变换更为常用。

离散傅里叶变换(DFT)的基本步骤如下:

  1. 对输入信号进行采样,得到离散时间信号。采样频率通常为原始信号频率的整数倍,以满足奈奎斯特采样定理。

  2. 对离散时间信号进行窗函数处理。窗函数的作用是减小信号截断引起的频谱泄漏,同时减小频谱旁瓣的影响。常用的窗函数有矩形窗、汉宁窗和海宁窗等。

  3. 计算离散时间信号的离散傅里叶变换。这可以通过快速傅里叶变换(Fast Fourier Transform,FFT)算法来实现,以提高计算效率。快速傅里叶变换是一种基于蝶形运算的高效算法,其计算复杂度为O(nlogn),其中n为信号长度。

  4. 对离散傅里叶变换的结果进行分析。通过观察频谱图,可以了解信号的频率分布、幅值和相位等信息。此外,还可以利用傅里叶变换的性质进行信号处理,例如滤波、降噪和压缩等。

傅里叶变换具有以下重要性质:

  1. 线性性质:傅里叶变换满足线性叠加原理,即两个信号的傅里叶变换之和等于这两个信号分别进行傅里叶变换后再相加的结果。

  2. 共轭对称性:对于实数信号,其傅里叶变换的共轭复数表示了信号的频谱。这意味着实数信号的频谱是以原点为中心的对称分布。

  3. 时移性质:对于任意实数τ,信号x(t)与其自身延时τ的信号x(t-τ)的傅里叶变换之比等于e^(j2πτ),其中j为虚数单位。这表明时移操作可以通过乘以复指数因子来实现。

  4. 频移性质:对于任意实数ω,信号x(t)与其频率为ω的信号cos(2πωt)的乘积的傅里叶变换等于X(f)与δ(f-ω)的卷积,其中δ(f)表示狄拉克δ函数。这表明频率调制可以通过乘以复指数因子和滤波操作来实现。

  5. 能量守恒:离散傅里叶变换的能量守恒性质表明,信号的总能量在时域和频域之间是平衡的。这意味着在频域中去除某些频率分量后,信号的总能量会相应地转移到其他频率分量上。

总之,傅里叶变换是一种强大的数学工具,广泛应用于通信、图像处理、音频处理、生物信息学等领域。通过傅里叶变换,我们可以更好地理解和分析信号的特性,从而实现信号的滤波、降噪、压缩等功能。

2.2 opencv中傅里叶变换

在数字图像处理中,空间域滤波和频域滤波都是常见的方法,但它们之间存在一些关键的区别。

  1. 空间域滤波:这种方法直接对图像进行操作,通常使用各种模板与图像进行卷积运算来实现图像的处理。由于其直接在图像空间上操作,这种方法的实现相对简单和直观。

  2. 频域滤波:频域滤波首先将图像从空间域转换到频域,然后对频率域中的图像数据进行处理,最后再将其转换回空间域。这种处理方法的优点在于,某些图像处理任务在频域中比在空间域中更为简单。例如,根据卷积定理,可以通过傅立叶变换将空域卷积滤波变换为频域滤波。此外,频域滤波允许设计者使用复杂的滤波器设计,这可能在空间域中难以实现。然而,需要注意的是,如果选用的频域滤波器具有陡峭的变化,可能会导致输出图像产生“振铃”现象,这是由于灰度剧烈变化处产生的。

在OpenCV库中,傅里叶变换和逆傅里叶变换的实现主要依赖于**cv2.dft()cv2.idft()**两个函数。在进行傅里叶变换时,你需要将原始图像转换为np.float32格式。

具体来说,cv2.dft()函数的定义是:cv2.dft(原始图像,转换标识)。其中,原始图像必须是np.float32格式,转换标识用于说明是傅里叶变换还是傅里叶逆变换。此函数返回与前一个相同的结果,但是有两个通道。第一个通道是结果的实部,第二个通道是结果的虚部。

另一方面,cv2.idft()函数被用来执行逆傅里叶变换。例如,如果你有一个通过傅里叶变换得到的复数矩阵,你可以使用这个函数来恢复原始图像。

需要注意的是,OpenCV提供的这两个函数的效率较高(比OpenCV自带的函数快3倍)。这是因为它们实现了一种称为快速傅立叶变换(FFT)的快速算法。

三、实验代码

from __future__ import print_function
import sys

import cv2 as cv
import numpy as np


def print_help():
    print('''
    代码演示离散傅里叶变换,同时也显示幅度谱''')

def main(argv):
    print_help()
    I = cv.imread("d:/Data/1.jpg", cv.IMREAD_GRAYSCALE)
    if I is None:
        print('Error opening image')
        return -1
    ## [expand]
    rows, cols = I.shape
    m = cv.getOptimalDFTSize( rows )
    n = cv.getOptimalDFTSize( cols )
    # 把图像边界拓展下
    padded = cv.copyMakeBorder(I, 0, m - rows, 0, n - cols, cv.BORDER_CONSTANT, value=[0, 0, 0])
    ## [complex_and_real]
    planes = [np.float32(padded), np.zeros(padded.shape, np.float32)]
    complexI = cv.merge(planes)         # Add to the expanded another plane with zeros
    ## [complex_and_real]
    ## [dft]
    cv.dft(complexI, complexI)         # this way the result may fit in the source matrix
    ## [dft]
    # compute the magnitude and switch to logarithmic scale
    # = > log(1 + sqrt(Re(DFT(I)) ^ 2 + Im(DFT(I)) ^ 2))
    ## [magnitude]
    cv.split(complexI, planes)                   # planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
    cv.magnitude(planes[0], planes[1], planes[0])# planes[0] = magnitude
    magI = planes[0]
    ## [magnitude]
    ## [log]
    matOfOnes = np.ones(magI.shape, dtype=magI.dtype)
    cv.add(matOfOnes, magI, magI) #  switch to logarithmic scale
    # 取log是为了拉伸值
    cv.log(magI, magI)
    ## [log]
    ## [crop_rearrange]
    magI_rows, magI_cols = magI.shape
    # crop the spectrum, if it has an odd number of rows or columns
    magI = magI[0:(magI_rows & -2), 0:(magI_cols & -2)]
    cx = int(magI_rows/2)
    cy = int(magI_cols/2)

    q0 = magI[0:cx, 0:cy]         # Top-Left - Create a ROI per quadrant
    q1 = magI[cx:cx+cx, 0:cy]     # Top-Right
    q2 = magI[0:cx, cy:cy+cy]     # Bottom-Left
    q3 = magI[cx:cx+cx, cy:cy+cy] # Bottom-Right

    tmp = np.copy(q0)               # 交换象限(左上和右下交换)
    magI[0:cx, 0:cy] = q3
    magI[cx:cx + cx, cy:cy + cy] = tmp

    tmp = np.copy(q1)               # 交换象限(右上和左下交换)
    magI[cx:cx + cx, 0:cy] = q2
    magI[0:cx, cy:cy + cy] = tmp
    # 归一化到 [0, 1]范围内
    cv.normalize(magI, magI, 0, 1, cv.NORM_MINMAX)
    # 原图得灰度图
    cv.imshow("Input Image"       , I   )
    # 幅度谱,也叫频谱
    cv.imshow("spectrum magnitude", magI)
    cv.waitKey()

if __name__ == "__main__":
    main(sys.argv[1:])

原图:

灰度图:

幅度谱如下:中间是高频区域、边界是低频区域、幅度谱是关于图像中心对称的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSAPP第四章:Y86 SEQ(指令顺序执行)的硬件结构

SEQ硬件结构的抽象表示。 程序计数器放在寄存器中(左下角,起点)。先向上,再向右 取指:将程序计数器寄存器作为地址,指令存储器读取一个指令的字节,PC增加器计算valP(程序计数器增加后的值)。 解码:寄存器…

openGauss学习笔记-125 openGauss 数据库管理-设置账本数据库-校验账本数据一致性

文章目录 openGauss学习笔记-125 openGauss 数据库管理-设置账本数据库-校验账本数据一致性125.1 前提条件125.2 背景信息125.3 操作步骤 openGauss学习笔记-125 openGauss 数据库管理-设置账本数据库-校验账本数据一致性 125.1 前提条件 数据库正常运行,并且对防…

创建一个用户test且使用testtab表空间及testtemp临时表空间并授予其权限,密码随意

文章目录 1、连接到数据库2、创建表空间创建testtab表空间创建testtemp临时表空间 3、创建用户4、授予权限5、测试 1、连接到数据库 sqlplus / as sysdba2、创建表空间 创建testtab表空间 CREATE TABLESPACE testtab DATAFILE /u01/app/oracle/oradata/orcl/testtab.dbf S…

【Spring】bean的基础配置

bean的别名 当在Spring config文件中定义name作为别名后&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instan…

关于 Git 你了解多少?

1. 什么是Git? Git 是一个版本控制系统&#xff0c;由林纳斯托瓦兹创建。它旨在管理项目代码的更改&#xff0c;以便团队成员可以协作开发和维护代码库。Git 可以让用户跟踪代码的更改、回滚错误的更改、合并代码等。Git 还具有分支和标签的功能&#xff0c;使得团队成员可以在…

个人简历管理系统winform

说明文档 运行前附加数据库.mdf&#xff08;或sql生成数据库&#xff09; 主要技术&#xff1a; 基于C#winform架构和sql server数据库 功能模块&#xff1a; 个人简历管理系统 简历信息添加 修改 删除 查询简历 运行环境&#xff1a; 运行需vs2013或者以上版本&#xff0…

Mistral 7B 比Llama 2更好的开源大模型 (三)

Mistral 7B 比Llama 2更好的开源大模型 Mistral 7B是一个70亿参数的语言模型,旨在获得卓越的性能和效率。Mistral 7B在所有评估的基准测试中都优于最好的开放13B模型(Llama 2),在推理、数学和代码生成方面也优于最好的发布34B模型(Llama 1)。Mistral 7B模型利用分组查询注…

Linux(1):开始

计算机组成概述 计算机&#xff1a;接受用户输入指令与数据&#xff0c;经由中央处理器的数学与逻辑单元处理后&#xff0c;以产生或存储有用的信息。 主要可以分为3个部分&#xff1a;输入单元、主机单元、输出单元。 中央处理器&#xff08;Central Processing Unit, CPU&a…

Linux | 进程间通信

目录 前言 一、进程间通信的基本概念 二、管道 1、管道的基本概念 2、匿名管道 &#xff08;1&#xff09;原理 &#xff08;2&#xff09;测试代码 &#xff08;3&#xff09;读写控制相关问题 a、读端关闭 b、写端关闭 c、读快写慢 d、读慢些快 &#xff08;4&a…

【JUC】九、线程池ThreadPool

文章目录 1、线程池2、分类3、线程池的使用4、工作流程5、拒绝策略6、线程池的七个参数7、自定义线程池8、什么时候考虑使用线程池&#xff1f; 1、线程池 线程池和数据库连接池的理念很相似&#xff0c;对于数据库连接池&#xff1a;普通的连接数据库是建立一个JDBC连接&…

目标检测一 SSD代码复现

SSD 背景 这是一种 single stage 的检测模型&#xff0c;相比于R-CNN系列模型上要简单许多。其精度可以与Faster R-CNN相匹敌&#xff0c;而速度达到了惊人的59FPS&#xff0c;速度上完爆 Fster R-CNN。 速度快的根本原因在于移除了 region proposals 步骤以及后续的像素采样或…

项目Git分支管理规范

Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 一、分支管理 项目中&#xff0c;一般会创建三个常用分支&#xff1a; develop&#xff1a;开发环境的稳定分支&#xff0c;公共开发环境基于该分支构建。pre-release&#xff1a;测试…

Zabbix钉钉机器人告警

目录 一.在钉钉群里添加机器人 二.配置钉钉告警脚本 1.安装python依赖模块python-requests 2.配置钉钉告警配置脚本zabbix_ding.conf 3.创建告警日志并且授权。 4.配置钉钉告警执行脚本dingding.py 5.测试 三.配置zabbix告警 1.创建媒介 2.给用户添加报警媒介 3.配置…

C++初阶--内存管理

文章目录 内存分布new/delete基本用法malloc/free和new/delete的区别进一步理解new和delete的实现原理 定位new&#xff08;了解&#xff09; 内存分布 栈&#xff08;stack&#xff09;&#xff1a;栈是由编译器自动管理的内存区域&#xff0c;用于存储局部变量&#xff0c;函…

OpenCV基础应用(3)— 把.png图像保存为.jpg图像

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本节课就手把手教你如何把.png图像保存为.jpg图像&#xff0c;希望大家学习之后能够有所收获~&#xff01;&#x1f308; 目录 &#x1f680;1.技术介绍 &#x1f680;2.实现代码 &#x1f680;1.技术介绍 如果在电脑某…

【以图会意】文件系统从外存到内存到用户空间

首先&#xff0c;在文件目录中&#xff0c;装有很多块FCB&#xff0c;由文件名和i指针两部分构成&#xff0c;指针指向文件所在的索引结点&#xff0c;包含了例如&#xff1a;文件存储权限&#xff0c;文件长度等一系列文件的信息&#xff0c;最重要的当然是物理地址&#xff0…

Python中带图例的条形图的具体画法和参数调节

首先如上图所示的图是如何画出来的呢&#xff0c;它主要是分三个部分&#xff0c; 首先第一部分是将四个单独的图按照横轴的方式叠加起来&#xff0c;第二部分是如何调节右上角图例的位置和大小&#xff0c;第三部分是标注出整个横轴和竖轴的坐标并调节字体的大小。 一.将四个…

QQ邮箱地址一键自动粘贴,工作效率迅速提升

您是否曾经为了输入邮箱地址而烦恼&#xff1f;每次需要输入邮箱地址时&#xff0c;总是要反复复制粘贴&#xff0c;不仅浪费时间&#xff0c;还容易出错。现在&#xff0c;我们为您带来了一项全新的QQ邮箱自动粘贴功能&#xff0c;让您的工作更加高效便捷&#xff01; 首先&a…

《变形监测与数据处理》笔记/期末复习资料(择期补充更新)

变形&#xff1a; 变形是物体在外来因素作用下产生的形状、大小及位置的变化&#xff08;随时间域和空间域的变化&#xff09;&#xff0c;它是自然界普遍存在的现象。 变形体&#xff1a; 一般包括工程建筑物、构筑物、大型机械设备以及其他自然和人工对象等。 变形体和变形…

华为鸿蒙开发记录

错误 1No module found. Make sure the project sync is completed successfully and the module is set in Edit Configuration > General 应该是项目建立的是Api是9 &#xff0c;但是 华为远程模拟器是应该建立的是 8的&#xff0c;导致 版本过低。从新建立项目选择APi8就…