dft转换与反转

2023-11-15

这次介绍下opencv中DFT的使用,对应的例程是(EXAMPLE) dft。在图像处理领域,通过DFT可以将图像转换到频域,实现高通和低通滤波;还可以利用矩阵的卷积运算等同于其在频域的乘法运算从而优化算法降低运算量, 即先将图像转换到频域,然后做完乘法运算后,再转换到图像域,opencv中的模板匹配就利用了这一特性降低运算量。

下面是dft例程的源码

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "opencv2/core/core.hpp"  
  2. #include "opencv2/imgproc/imgproc.hpp"  
  3. #include "opencv2/highgui/highgui.hpp"  
  4.   
  5. #include <stdio.h>  
  6.   
  7. using namespace cv;  
  8. using namespace std;  
  9.   
  10. static void help()  
  11. {  
  12.     printf("\nThis program demonstrated the use of the discrete Fourier transform (dft)\n"  
  13.            "The dft of an image is taken and it's power spectrum is displayed.\n"  
  14.            "Usage:\n"  
  15.             "./dft [image_name -- default lena.jpg]\n");  
  16. }  
  17.   
  18. const char* keys =  
  19. {  
  20.     "{1| |lena.jpg|input image file}"  
  21. };  
  22.   
  23. int main(int argc, const char ** argv)  
  24. {  
  25.     help();  
  26.     CommandLineParser parser(argc, argv, keys);        // opencv中用来处理命令行参数的类  
  27.     string filename = parser.get<string>("1");  
  28.   
  29.     Mat img = imread(filename.c_str(), CV_LOAD_IMAGE_GRAYSCALE);    //以灰度图像读入  
  30.     if( img.empty() )  
  31.     {  
  32.         help();  
  33.         printf("Cannot read image file: %s\n", filename.c_str());  
  34.         return -1;  
  35.     }  
  36.     int M = getOptimalDFTSize( img.rows );                               // 获得最佳DFT尺寸,为2的次方  
  37.     int N = getOptimalDFTSize( img.cols );                                 //同上  
  38.     Mat padded;  
  39.     copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));   // opencv中的边界扩展函数,提供多种方式扩展  
  40.   
  41.     Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};          // Mat 数组,第一个为扩展后的图像,一个为空图像,  
  42.     Mat complexImg;                                                                                                      
  43.     merge(planes, 2, complexImg);                                                                              // 合并成一个Mat  
  44.   
  45.     dft(complexImg, complexImg);                                                                              // FFT变换, dft需要一个2通道的Mat  
  46.   
  47.     // compute log(1 + sqrt(Re(DFT(img))**2 + Im(DFT(img))**2))  
  48.     split(complexImg, planes);                                                                                     //分离通道, planes[0] 为实数部分,planes[1]为虚数部分  
  49.     magnitude(planes[0], planes[1], planes[0]);                                                          // 求模  
  50.     Mat mag = planes[0];  
  51.     mag += Scalar::all(1);                                                                                              
  52.     log(mag, mag);                                                                                                      // 模的对数  
  53.   
  54.     // crop the spectrum, if it has an odd number of rows or columns  
  55.     mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));                                        //保证偶数的边长  
  56.   
  57.     int cx = mag.cols/2;  
  58.     int cy = mag.rows/2;  
  59.   
  60.     // rearrange the quadrants of Fourier image                                                        //对傅立叶变换的图像进行重排,4个区块,从左到右,从上到下 分别为q0, q1, q2, q3  
  61.     // so that the origin is at the image center                                                          //  对调q0和q3, q1和q2  
  62.     Mat tmp;  
  63.     Mat q0(mag, Rect(0, 0, cx, cy));  
  64.     Mat q1(mag, Rect(cx, 0, cx, cy));  
  65.     Mat q2(mag, Rect(0, cy, cx, cy));  
  66.     Mat q3(mag, Rect(cx, cy, cx, cy));  
  67.   
  68.     q0.copyTo(tmp);  
  69.     q3.copyTo(q0);  
  70.     tmp.copyTo(q3);  
  71.   
  72.     q1.copyTo(tmp);  
  73.     q2.copyTo(q1);  
  74.     tmp.copyTo(q2);  
  75.   
  76.     normalize(mag, mag, 0, 1, CV_MINMAX);                                                           // 规范化值到 0~1 显示图片的需要  
  77.   
  78.     imshow("spectrum magnitude", mag);  
  79.     waitKey();  
  80.     return 0;  
  81. }  
下图为运行结果,

例程只介绍了将图像转换到频域,那如何将其逆变换转换成图像呢?opencv中提供逆变换的函数为idft,下面看下dft,idft这两个函数的原型

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //! performs forward or inverse 1D or 2D Discrete Fourier Transformation  
  2. CV_EXPORTS_W void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0);  
  3. //! performs inverse 1D or 2D Discrete Fourier Transformation  
  4. CV_EXPORTS_W void idft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0);  

从描述可以看出,dft,idft分别用于实现1维,2维的傅立叶变换和傅立叶逆变换。此时你或许可能认为opencv为dft,idft分别写了两个函数实现,但如果查看idft的源码,你会发现idft的实现也是在dft函数中,opencv中代码的重用率还是挺高的。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. void cv::idft( InputArray src, OutputArray dst, int flags, int nonzero_rows )  
  2. {  
  3.     dft( src, dst, flags | DFT_INVERSE, nonzero_rows );  
  4. }  

通过一个flags来控制是进行dft变换还是idft变换,这种用法在opencv中十分的普遍。我们可以在程序中添加一些代码

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1.     Mat ifft;  
  2.     idft(complexImg,ifft,DFT_REAL_OUTPUT);  
  3.     normalize(ifft,ifft,0,1,CV_MINMAX);  
  4.     imshow("idft",ifft);  
 实现DFT的逆变换

结果如下图所示


可以看出逆变换后的图像内容与原图是一样的,因为我们进行任何处理,但是idf的大小比原图要大一些,且有些黑色边界,这是由于dft需要保证边长长度为2的次方,在这种情况下,计算速度可以加速,因此在之前的处理过程中,将原图的大小调整到2的次方,黑色边界便是copyMakeBoder的0值填充所形成的,这个函数在插值,滤波,掩模操作中十分常用,被用来扩展边界以是图像边界上的像素也能得以处理,只不过在那些操作中,处理完的图片与原图一样大小。

傅立叶变换还有一个特性经常被利用到,就是它的相位,用来确定图像的选择角度,例如tutorial文档中就提到一个应用,用来确定文字的旋转角度,我们可以通过将一张图像旋转一定的角度来做一个实验,下面是结果。


可以看出沿着中心的两个轴随着图像的旋转而旋转,因此通过确定轴的旋转角度,便可以将图像位置调整过来,相应的,处理的如果是文字或者是车牌,也可以通过类似的处理进行对齐和角度调整。

对频域图像阈值处理后,可以看得更加清楚。

链接:http://blog.csdn.net/u011503970/article/details/18623913

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

dft转换与反转 的相关文章

  • OpenCV:处理每一帧

    我想使用 OpenCV 编写一个跨平台应用程序进行视频捕获 在所有示例中 我发现来自相机的帧是使用抓取功能进行处理并等待一段时间 我想处理序列中的每一帧 我想定义自己的回调函数 每次当一个新帧准备好处理时都会执行该函数 例如直播对于 Win
  • 如何在 OpenCV 中删除 mouseCallback

    在使用 C 的 OpenCV 中 有没有办法删除 mouseHandler int event int x int y int flags void param 通过函数添加到窗口 image window cv setMouseCallb
  • 将 RGB 转换为黑色或白色

    我如何在Python中获取RGB图像并将其转换为黑白图像 不是灰度 我希望每个像素要么是全黑 0 0 0 要么是全白 255 255 255 流行的 Python 图像处理库中是否有任何内置功能可以完成此任务 如果不是 最好的方法是循环遍历
  • 如何在 CMake Makefile 中包含 OpenCV 库

    我希望你可以帮助我 我有一个简单的 CMakeLists txt 以便在 Leopard 10 5 8 上构建我的项目 我正在使用 CMake 2 8 1 目前这是代码 cmake minimum required VERSION 2 8
  • OpenCV Python 删除图像中的某些对象

    我正在使用带有 opencv 和 numpy 的 python 来检测天文中的星星 例如这个1 https i stack imgur com AKwEJ jpg图片 使用模板匹配 我可以用阈值检测星星 单击 2 2 https i sta
  • 如何计算立体视觉的基本矩阵

    我正在尝试编写一些代码来计算基本矩阵以确定立体图像之间的关系 我从大多数人推荐的 Hartley 和 Zisserman 书开始 但它没有任何实际示例 并且示例代码是在 MATLAB 中 而我没有 然后我切换到这个比较实用 里面有实际例子
  • Opencv - 找不到头文件

    我正在尝试使用 opencv 开始开发 问题是 到目前为止我几乎无法设置 opencv 因为我找不到它的头文件 我对此主题进行了一些研究 但没有一个真正有帮助 下面是一些链接 opencv2 包含文件在哪里 https stackoverf
  • 将线性数组转换为二维矩阵

    我有一个浮点指针 数组 它代表一个图像 它的元素计数和索引具有宽度 高度 图像不像矩阵 其原点位于左上角 相反 它的原点位于左下角 就像在笛卡尔坐标系中一样 达到最大宽度后 它从左侧开始下一行 所以我想有效地将 这个数组转换为二维矩阵 可选
  • ValueError:当数组不是序列时设置带有序列的数组元素

    您好 此代码旨在存储使用 open cv 绘制的矩形的坐标 并将结果编译为单个图像 import numpy as np import cv2 im cv2 imread 1 jpg im3 im copy gray cv2 cvtColo
  • 使用 SURF 在检测到的对象周围绘制矩形

    我正在尝试从涉及冲浪检测器的以下代码中检测对象 我不想绘制匹配项 我想在检测到的对象周围绘制一个矩形 但不知何故我无法获得正确的单应性 请任何人指出在哪里我走错了 include
  • 使用 OpenCV 和 Python 叠加两个图像而不丢失颜色强度

    如何叠加两个图像而不损失两个图像的颜色强度 我有图像1和图像2 2 我尝试使用 0 5 alpha 和 beta 但它给我的合并图像的颜色强度只有一半 dst cv2 addWeighted img1 0 5 img2 0 5 0 但是当我
  • 如何确定透视变换后的点在新图像平面中的位置?

    我使用 OpenCV Python Numpy 图像中有三个点 我知道这些点的确切位置 P1 P2 N1 我要将图像转换为另一个视图 例如 我将透视图转换为侧视图 如果这样做 我将无法获得图像平面中这三个点的确切位置 我应该以一种可以获得这
  • Android API人脸检测与OpenCV/JavaCV人脸检测

    我在 Android 设备上使用了本地 Android 人脸检测 但它似乎很慢 而且我不太确定其可靠性 我还使用了 OpenCV 的人脸检测 但仅限于 PC 而不是 Android 设备 对于 Android 我猜我必须使用 JavaCV
  • 在OpenCV中将YUV转换为BGR或RGB

    我有一个电视采集卡 其输入内容为 YUV 格式 我在这里看到了与此问题类似的其他帖子 并尝试尝试所述的所有可能的方法 但它们都没有提供清晰的图像 目前最好的结果是 OpenCVcvCvtColor scr dst CV YUV2BGR 函数
  • 类型错误:只有长度为 1 的数组可以转换为 Python 标量

    我是 openCV 的初学者 正在尝试分析数独求解器的现有代码 有这一段代码会引发错误 samples np float32 np loadtxt feature vector pixels data responses np float3
  • 如何平滑循环列向量

    这是一个 OpenCV2 问题 我有一个矩阵代表closed空间曲线 cv Mat
  • 将向量 转换为大小为 (n x 3) 的 Mat,反之亦然

    我有 Point3d 向量 向量形式的点云 如果我使用 OpenCV 提供的转换 比如 cv Mat tmpMat cv Mat pts Here pts is vector
  • OpenCV 中的 Gabor 内核参数

    我必须在我的应用程序中使用 Gabor 过滤器 但我不知道这个 OpenCV 方法参数值 我想对虹膜进行编码 启动 Gabor 过滤器并获取特征 我想对 12 组 Gabor 参数值执行此操作 然后我想计算 Hamming Dystans
  • 如何将 Opencv VideoWriter 与 GStreamer 结合使用?

    我正在尝试使用 Opencv VideoWriter 传输 h264 流 以使用 VideoCapture 将其传输到网络上的另一台电脑上 但是 我被困在 VideoWriter 上 执行此代码会返回错误 并且 out isOpened 始
  • 计数物体和更好的填充孔的方法

    我是 OpenCV 新手 正在尝试计算物体的数量在图像中 我在使用 MATLAB 图像处理工具箱之前已经完成了此操作 并在 OpenCV Android 中也采用了相同的方法 第一步是将图像转换为灰度 然后对其进行阈值计算 然后计算斑点的数

随机推荐

  • Java 重写 equals和hashcode

    重写equals方法的时候为什么需要重写hashcode
  • SqlServe--从字符串中提取数字

    1 基础使用 声明一个nvarchar类型的变量并赋值 declare Name nvarchar 50 set Name 我正在123学 习22 SQL中11 的一些函数 patindex函数返回所查内容在字符串中第一次出现的内容 pri
  • STM32 (十五)ESP8266WIFI

    简介 1 ESP8266wifi 模块 低功耗串口WiFi模块ESP8266内置一个Tensilica 泰思立达 Xtensa架构的32位处理器L106 具有5级流水线 ARM CortexM3是3级流水线 最大时钟速度为160MHz 可以
  • JMM简单理解

    JMM java内存模型 代码理解 public class test private static boolean f false public static void main String args throws Interrupte
  • Python日志记录基础教程:logging模块详解与示例代码

    Python日志记录基础教程 logging模块详解与示例代码 在Python应用程序的开发过程中 日志记录是一个重要的组成部分 它能够帮助开发人员追踪和调试代码 并记录应用程序的运行情况 Python标准库中的logging模块提供了一个
  • 【计算机视觉

    文章目录 一 CBC Complete Blood Count 二 CURE TSD CURE Traffic Sign Detection 三 DUO Detecting Underwater Objects 四 Duke Breast
  • 方法的重写-overrideoverwrite

    方法的重写 override overwrite 1 定义 定义 子类继承父类以后 可以对父类中同名同参数的方法 进行覆盖操作 应用 重写以后 当创建子类对象以后 通过子类对象调用子父类中的同名同参数的方法时 实际执行的是子类重写的方法 使
  • 2D和3D人体姿态数据集

    转自链接 https www jianshu com p c046db584a21 2D数据集 LSP 地址 http sam johnson io research lsp html 样本数 2k 关节点数 14 全身 单人 FLIC 地
  • 用go实现一个telnet带上账号密码的协议请求

    实现一个telnet协议请求 需要用到网络编程的知识 下面是一份简单的代码示例 package main import bufio fmt net strings func main ln err net Listen tcp 8080 i
  • 数据结构之直接插入排序(算法思想,复杂度分析)以及冒泡排序和直接插入排序的比较

    一般来说 插入排序都采用in place在数组上实现 具体算法描述如下 从第一个元素开始 该元素可以认为已经被排序 取出下一个元素 在已经排序的元素序列中从后向前扫描 如果该元素 已排序 大于新元素 将该元素移到下一位置 重复步骤3 直到找
  • 【算法入门12】链表合并

    核心考点 链表合并 思维缜密程度 输入两个递增的链表 合并这两个链表并使新链表中的结点仍然是递增排序的 解析一 常规 合并两个链表最常规的做法就是 依次比较两个链表的第一个结点 取较小的结点 此处为递增排序 尾插到一个新链表后 直到其中一个
  • C语言 缓存区溢出 3221225725

    目录 问题描述 解决办法 问题描述 DEV C报错 Process exited after 4 03 seconds with return value 3221225725 原因 数组定义的容量太大 五十万起步的样子 而且每次循环都会再
  • Laravel定时任务的每秒执行

    我的个人博客 逐步前行STEP laravel中的任务调度可以不将每条命令都写入crontab 便于管理维护 而且可以基于laravel框架环境运行 而不需写独立的脚本执行 非常方便 但是最小的执行间隔也是一分钟 要想达到每秒执行的效果 就
  • 2018.7.18 something you want to replace

    Something I want to replace is iphone6 which looks like a small box When I come to university my parents brought me this
  • 【C++ Core Guidelines解析】C++学习之路的一盏明灯

    前言 C 语言的功能非常丰富 表达能力非常强 因为一种成功的通用编程语言拥有的功能必须比任何开发人员所需要的更多 任何一种有生命力且不断发展的语言都会不断积累用于表达程序员思想的替代用法 这会导致选择过载 那么 开发人员应该如何根据编程风格
  • 旧手机改服务器,并配合花生壳实现外网访问的方法

    旧手机改服务器 并配合花生壳实现外网访问的方法 前提准备 开始手机端操作 开始电脑端操作 至此所有操作结束 前提准备 1 手机必须root 2 busybox 3 linux deploy 4 花生壳安卓内网穿透版 下载时注意 有个管理版
  • 测试开发学习路线

    测试开发学习路线 HI 大家好 我是Lee 通过某些圈子了解大家对于测试开发这个岗位了解的很模糊 对于技术栈不知道应该学习什么 接下来就通过各方面来说一下测试开发具体是做什么以及需要掌握哪些技术 1 了解测试开发 什么是测试开发 大家应该都
  • 【学习笔记】mybatis-generator自动生成工具的使用教程 2021最新版

    一 什么是mybatis generator mybatis geneator是一款mybatis自动代码生成工具 可以通过配置 快速生成DAO POJO和xml等文件 二 如何在IDEA上使用mybatis generator 1 导入依
  • Redis Stream 数据结构实现原理真的很强

    1 是什么 Stream 是 Redis 5 0 版本专门为消息队列设计的数据类型 借鉴了 Kafka 的 Consume Group 设计思路 提供了消费组概念 同时提供了消息的持久化和主从复制机制 客户端可以访问任何时刻的数据 并且能记
  • dft转换与反转

    这次介绍下opencv中DFT的使用 对应的例程是 EXAMPLE dft 在图像处理领域 通过DFT可以将图像转换到频域 实现高通和低通滤波 还可以利用矩阵的卷积运算等同于其在频域的乘法运算从而优化算法降低运算量 即先将图像转换到频域 然