基本原理

离散傅里叶变换(Discrete Fourier reansform, 缩写为DFT),是指傅里叶变换在时域和频域上都呈现离散的形式,将时域信号的采样变换为在离散时间傅里叶变换频域的采样。简单来说,对一张图像做傅里叶变换,就是将它分解为 sin 和 cos 两部分,也就是将图像从空间域(spatial domain)转换到频域(frequency domian)。可以使用欧拉公式进行转换,如图所示:

变换结果F(u,v)是复数,包含实部和虚部两部分:

幅度图像包含了几乎所有我们需要的几何信息,一般我们只需要使用幅度图像。如果想通过傅里叶变换修改原图像,可以先修改幅度图像,再将幅度图像与相位图像进行逆变换得到结果图像。

但傅立叶系数的动态范围太大,无法在屏幕上显示出来。为了使用灰度值进行可视化,我们可以将线性刻度的幅值图转换为对数刻度:
M1=log(1+M)

opencv中傅里叶变换的API:

void dft(InputArray src, OutputArray dst, int flags=0, int nonzeroRows=0);

由公式(1)可得:

因此,也可以使用 dft() 函数进行傅里叶逆变换。

在图像处理中的应用

傅立叶变换在图像处理中有非常多的作用。因为不仅傅立叶分析涉及图像处理的很多方面,傅立叶的改进算法,比如离散余弦变换,gabor与小波在图像处理中也有重要的分量。傅里叶变换在以下几个方面都有应用:

以下对傅里叶变换在图像旋转方向的应用进行实现,共分为4个步骤:
(1)对原图进行DFT变换,得到复数F(u,v);
(2)由实部、虚部合成幅值图,并进行M1=log(1+M)转换;
(3)重新排布幅值图像的4个象限,使原点位于图像中心,高频在角落,并将幅度转化为[ 0, 255 ]
(4)使用霍夫变换查找直线,计算旋转角度,旋转图像

实现代码如下:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <ctime>
#include "math.h"using namespace cv;
using namespace std;int main(int argc, char** argv)
{//以单通道(灰度)方式读取图像const char* filename = "../data/blue.jpg";Mat srcImg = imread(filename, CV_LOAD_IMAGE_GRAYSCALE);if (srcImg.empty())return -1;Point center(srcImg.cols / 2, srcImg.rows / 2);clock_t start = clock();//将图像扩展到最佳大小,以获得更快的处理速度//设置4个方向的边框宽度//如果 borderType==BORDER_CONSTANT, 用(0,0,0)填充Mat padded;int opWidth = getOptimalDFTSize(srcImg.rows);int opHeight = getOptimalDFTSize(srcImg.cols);copyMakeBorder(srcImg, padded, 0, opWidth - srcImg.rows, 0, opHeight - srcImg.cols, BORDER_CONSTANT, Scalar::all(0));Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };Mat comImg;//合并成一个双通道图像merge(planes, 2, comImg);//傅里叶变换dft(comImg, comImg);//计算幅值//复数形式:planes[0]=Re(DFT(I)), planes[1]=Im(DFT(I)), magnitude=sqrt(Re^2+Im^2)split(comImg, planes);magnitude(planes[0], planes[1], planes[0]);//转换到log的尺度下,从而能观察到图像(否则数据过界)//M2=log(1+M1)Mat magMat = planes[0];magMat += Scalar::all(1);log(magMat, magMat);//剪切和重分布幅度图象限//若有奇数行或奇数列,进行裁剪magMat = magMat(Rect(0, 0, magMat.cols & -2, magMat.rows & -2));//重新排布傅里叶图像的4个象限,使原点位于图像中心,高频在角落int cx = magMat.cols / 2;int cy = magMat.rows / 2;Mat q0(magMat, Rect(0, 0, cx, cy));Mat q1(magMat, Rect(0, cy, cx, cy));Mat q2(magMat, Rect(cx, cy, cx, cy));Mat q3(magMat, Rect(cx, 0, cx, cy));//交换象限Mat tmp;q0.copyTo(tmp);q2.copyTo(q0);tmp.copyTo(q2);q1.copyTo(tmp);q3.copyTo(q1);tmp.copyTo(q3);//将幅度标准化至 [0,1], 再转为[0,255]normalize(magMat, magMat, 0, 1, CV_MINMAX);Mat magImg(magMat.size(), CV_8UC1);magMat.convertTo(magImg, CV_8UC1, 255, 0);   // 像素值*255+0//以下部分是对频谱图像进行霍夫直线变换,找到角度值,利用该角度值对原图像进行旋转,多适用于文字图像//转为二值图像threshold(magImg, magImg, 150, 255, CV_THRESH_BINARY);//旋转原图//使用霍夫变换查找直线vector<Vec2f> lines;float pi180 = (float)CV_PI / 180;Mat linImg(magImg.size(), CV_8UC3);HoughLines(magImg, lines, 1, pi180, 500, 0, 0);int numLines = lines.size();for (int l = 0; l < numLines; l++){float rho = lines[l][0], theta = lines[l][1];Point pt1, pt2;double a = cos(theta), b = sin(theta);double x0 = a * rho, y0 = b * rho;pt1.x = cvRound(x0 + 1000 * (-b));pt1.y = cvRound(y0 + 1000 * (a));pt2.x = cvRound(x0 - 1000 * (-b));pt2.y = cvRound(y0 - 1000 * (a));line(linImg, pt1, pt2, Scalar(255, 0, 0), 1, 8, 0);}//imwrite("imageText_line.jpg",linImg);if (lines.size() == 3) {cout << "found three angels:" << endl;cout << lines[0][1] * 180 / CV_PI << endl << lines[1][1] * 180 / CV_PI << endl << lines[2][1] * 180 / CV_PI << endl << endl;}//Find the proper angel from the three found angelsfloat angel = 0;float piThresh = (float)CV_PI / 90;float pi2 = CV_PI / 2;for (int l = 0; l < numLines; l++){float theta = lines[l][1];if (abs(theta) < piThresh || abs(theta - pi2) < piThresh)continue;else {angel = theta;break;}}//计算旋转角度//如果图像不是方的,旋转后可能会达不到预期效果angel = angel < pi2 ? angel : angel - CV_PI;if (angel != pi2) {float angelT = srcImg.rows * tan(angel) / srcImg.cols;angel = atan(angelT);}float angelD = angel * 180 / (float)CV_PI;cout << "the rotation angel to be applied:" << endl << angelD << endl << endl;clock_t end = clock();cout << "花费了" << (double)(end - start) / CLOCKS_PER_SEC << "秒" << endl;//旋转图像Mat rotMat = getRotationMatrix2D(center, angelD, 1.0);Mat dstImg = Mat::ones(srcImg.size(), CV_8UC3);warpAffine(srcImg, dstImg, rotMat, srcImg.size(), 1, 0, Scalar(0, 0, 0));return 0;
}

实现结果如下图所示:

本文仅对傅里叶变换在图像旋转方向的应用进行了实现,今后将针对其他几个领域进行举例实现。对于代码中的相关函数的使用,在图像旋转的实现中没有进行过多研究。如有必要,今后会重新修改本篇博文进行介绍。

参靠文献:
OpenCV教程
CSDN博文_01
CSDN博文_02
非常详细的B站教程

傅里叶变换在图像处理中的应用相关推荐

  1. 傅里叶变换在图像处理中的应用初步学习

    1 理解傅里叶变换在图像处理中的应用 一维傅里叶变换的作用对象是信号,信号是一维连续的:随着时间不断推移,信号强度的变换情况,可称为时域. 图像处理中的傅里叶变换的作用对象是二维矩阵.随着位置的不断改 ...

  2. 傅里叶变换在图像处理中的作用

    傅立叶变换在图像处理中非常的有用.因为不仅傅立叶分析涉及图像处理的很多方面,傅立叶的改进算法, 比如离散余弦变换,gabor与小波在图像处理中也有重要的分量. 印象中,傅立叶变换在图像处理以下几个话题 ...

  3. java 图像傅里叶变换_傅里叶变换在图像处理中的作用

    傅立叶变换在图像处理中非常的有用.因为不仅傅立叶分析涉及图像处理的很多方面,傅立叶的改进算法, 比如离散余弦变换,gabor与小波在图像处理中也有重要的分量. 印象中,傅立叶变换在图像处理以下几个话题 ...

  4. 图像处理:如何理解傅里叶变换在图像处理中的应用

    声明:               这篇文章的主要目的是通过建立一维傅里叶变换与图像傅里叶变换中相关概念的对应关系来帮助读者理解图像处理中的离散傅里叶变换,因此,理解图像中离散傅里叶变换的前提条件是读 ...

  5. 【数字图像处理】傅里叶变换在图像处理中的应用

    from:https://www.cnblogs.com/tenderwx/p/5245859.html 1.理解二维傅里叶变换的定义 1.1二维傅里叶变换 二维Fourier变换: 逆变换: 1.2 ...

  6. 傅立叶变换在图像处理中的作用

    傅立叶变换在图像处理中有非常非常的作用.因为不仅傅立叶分析涉及图像处理的很多方面,傅立叶的改进算法, 比如离散余弦变换,gabor与小波在图像处理中也有重要的分量. 印象中,傅立叶变换在图像处理以下几 ...

  7. 傅立叶变换在图像处理中的应用

    1.为什么要进行傅里叶变换,其物理意义是什么? 傅立叶变换是数字信号处理领域一种很重要的算法.要知道傅立叶变换算法的意义,首先要了解傅立叶原理的意义.傅立叶原理表明:任何连续测量的时序或信号,都可以表 ...

  8. [转载]傅立叶变换在图像处理中的作用

    原文地址:傅立叶变换在图像处理中的作用作者:白屋顶黑乌鸦 从现代数学的眼光来看,傅里叶变换是一种特殊的积分变换.它能将满足一定条件的某个函数表示成正弦基函数的线性组合或者积分.在不同的研究领域,傅里叶 ...

  9. 傅里叶变换在图像处理的意义和应用

    图像傅里叶变换的物理意义: 图像的频率是表征图像中灰度变化剧烈程度的指标,是灰度在平面空间上的梯度.如:大面积的沙漠在图像中是一片灰度变化缓慢的区域,对应的频率值很低:而对于地表属性变换剧烈的边缘区域 ...

最新文章

  1. 如何利用离散Hopfield神经网络进行高校科研能力评价(1)
  2. 引用次数在 15000 次以上的都是什么神仙论文?
  3. Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-4.3.xsd).
  4. 1v1项目实战+真实经验倾囊相授,0基础的我是如何逆袭成功?
  5. EmbossMaskFilter BlurMaskFilter 学习
  6. GIS应用技巧之定义图框样式
  7. Endnote常见错误
  8. Python如何使用Continue语句?用法示例
  9. The Timebox
  10. python画五角星-Python的画五角星
  11. 计算机组装需要注意什么东西,电脑DIY:电脑组装时应该注意的几个细节以及方法...
  12. 存储新纪元:在DNA存储海量信息,商业化才是硬道理
  13. axWindowsMediaPlayer简单介绍
  14. 易订货专属App文档
  15. 最强大的四款windows办公软件,建议低调收藏!
  16. 如何使用新版本的万能地图下载器下载谷歌电子地图
  17. ubuntu 12.04安装截图功能的软件 gimp
  18. TTA(测试时增强)
  19. 浅谈对美国主机进行空间设计的方法
  20. 7个不容错过的jQuery图片动画及源码

热门文章

  1. 手机版Excel Office跳过登录
  2. 英语老师怎么抓学生成绩
  3. uniapp 微信公众号 扫一扫
  4. C++中大括号{}的作用
  5. B. Nick and Array 简单简洁
  6. bi管理驾驶舱平台哪个好?
  7. 听闻骨折与骨头的故事
  8. 排序算法汇总--冒泡,插入,归并,快速,堆,计数,基数,桶排序
  9. 【Mysql】MySQL 用户执行存储过程的权限
  10. java 面试题总结