注:本系列来自于图像处理课程实验。用Matlab实现最主要的图像处理算法


1.Fourier变换

(1)频域增强

除了在空间域内能够加工处理图像以外。我们还能够将图像变换到其它空间后进行处理。这些方法称为变换域方法,最常见的变换域是频域

使用Fourier变换把图像从空间域变换到频域。在频域内做对应增强处理,再从频域变换到空间域得到处理后的图像。

我们这里主要学习Fourier变换和FFT变换的算法,没有学过通信原理,我对信号、时域分析也不是非常清楚。


2.FFT算法

(1)离散Fourier变换。DFT

函数f(x)的DFT F(v)的计算式为:

F(v)=∑x=1Nf(x)e−i2πvxN,v=1,2,...,N

非常显然求出全部的长度为N的信号的DFT须要N×O(N)=O(N2)的时间。比較慢,因此我们须要引入时间复杂度为O(NlogN)的FFT算法。

(2)高速Fourier变换,FFT

高速傅立叶变换FFT是利用单位复数根的特殊性质(消去引理和折半引理。见《算法导论》(第3版中文版)P532具体论述),在O(NlogN)时间内计算出DFT的一种高速算法。

FFT有两种基本实现方式:

  • 递归FFT
  • 迭代FFT,也叫FFT蝶式运算

递归FFT因为递归栈开销大且容量有限等缺陷(但理解easy)。一般计算採取迭代FFT实现。

(3)迭代FFT

直接给出算法导论版本号的迭代FFT算法:

当中求逆序数拷贝的函数为:

FFT採用折半迭代的思想。因此速度能减少到O(NlogN)。

(4)迭代FFTMatlab实现

Matlab有fft函数,我们也能够自己实现:

function [ fft_m ] = IterativeFFT( vec )
clear i; n = length(vec); fft_m = BitReverseCopy(vec);
for s = 1 : log2(n)
m = power(2, s);
wm = exp(- 2 * pi * i / m); for k = 0 : m : n - 1
w = 1;
for j = 0 : m / 2 - 1
t = w * fft_m(k + j + m / 2 + 1);
u = fft_m(k + j + 1);
fft_m(k + j + 1) = u + t;
fft_m(k + j + m / 2 + 1) = u - t;
w = w * wm;
end
end
end
end

BitReverseCopy函数例如以下:

function [ copy ] = BitReverseCopy( vec )
n = length(vec);
copy = zeros(1, n); bitn = log2(n); for i = 0 : n - 1
revi = bin2dec(fliplr(dec2bin(i, bitn)));
copy(revi + 1) = vec(i + 1);
end
end

须要特别注意的是:

  • 一般给出的FFT算法伪代码都是基于下标从零開始的数组,写在Matlab须要考虑映射关系
  • clear i是为了怕之前有变量i和复数记号i混淆,清楚Matlab workspace中的缓存
  • 默认vec是double类型的!

    因为中间採用很多double类型运算


3.图像的二维Fourier变换

(1)二维DFT

二维DFT定义公式为:

F(u,v)=∑x=1N∑y=1Nf(x,y)e−i2π(ux+vy)N,u,v=1,2,...,N

计算一个频域点须要O(N2)的时间,那么整个二维频域计算须要O(N4)的时间,效率非常低。

(2)将二维DFT分解为两个一维DFT

Fourier变换的变换核(公式中和f(x,y)无关的部分)具有对称的性质(详见《图像project(上冊)图像处理》P81),因此利用对称性能够将二维DFT分解为两个一维DFT:

先对二维矩阵的每一列做一维DFT:

F(x,v)=∑y=1Nf(x,y)e−i2πvyN,v=1,2,...,N

再对变换后的矩阵的每一行做一维DFT:

F(u,v)=∑x=1NF(x,v)e−i2πuxN,u=1,2,...,N

最后以2×N×O(N2)=O(N3)的时间完毕二维傅立叶变换。

(3)用一维FFT实现二维FFT

相同的我们能够用两个一维FFT实现二维FFT,时间复杂度O(N2logN):

function [ mfft2 ] = JCGuoFFT2( data )
h = size(data, 1);
w = size(data, 2);
mfft2 = data; if power(2, log2(h)) ~= h || power(2, log2(w)) ~= w
disp('JCGuoFFT2 exit: h and w must be the power of 2!')
else
for i = 1 : h
mfft2(i, :) = IterativeFFT(mfft2(i, :));
end for j = 1 : w
mfft2(:, j) = IterativeFFT(mfft2(:, j));
end
end
end

代码非常简单。先做FFT行变换再做FFT列变换。之前忘记提到。我这里实现的都是长度必须是2的次方的Fourier变换,因此有时候会做一些长度规范检查。

(4)变换结果

经过JCGuoFFT2的二维傅立叶变换。我们能够得到复平面内各个点的复数值,那么显示在图像中须要先求出幅值:

pic1_fft = JCGuoFFT2(double(pic1));
pic1_fft_amp = abs(pic1_fft);

在对幅值做一次log变换得到较好的频域图像:

pic1_fft_amp_log = log(1 + pic1_fft_amp);

绘制结果例如以下图:

(5)低频信号移到图像中心点

因为复数运算的周期特性。图像的Fourier变换在复平面上是全然对称的,能够想象平面是由无限多个上图(右)频域图像拼接而成的二维阵列。

一般研究频域图像是把低频部分,也就是变换后的边缘部分移到图像中心点,Matlab提供fftshift函数完毕平移。

平移的思路有两个

  • 通过Fourier变换平移定理先把原始图像做变换再做FFT
  • 先做FFT后再依据频域图像的对称性做对称变换

查阅Matlab文档发现它是採用另外一种方法。对图像做下面子矩阵交换:

那么我们能够非常easy的写出自己的fftshift

function [ after ] = FFTShift( before )
h = size(before, 1);
w = size(before, 2); after = before; if power(2, log2(h)) ~= h || power(2, log2(w)) ~= w
disp('FFTShift exit: h and w must be the power of 2!')
else
hh = h / 2;
hw = w / 2;
after(1 : hh, 1 : hw) = before(hh + 1 : h, hw + 1 : w);
after(1 : hh, hw + 1 : w) = before(hh + 1 : h, 1 : hw);
after(hh + 1 : h, 1 : hw) = before(1 : hh, hw + 1 : w);
after(hh + 1 : h, hw + 1 : w) = before(1 : hh, 1 : hw);
end
end

将低频部分平移到中心点后结果为:


4.图像的二维反Fourier变换

(1)一维逆DFT和一维逆FFT

一维离散傅立叶变换的逆变换是将e的指数部分变号,然后总体除以长度N(Fourier变换与逆变换关于符号、系数有非常多种组合的定义,但他们都是等价且对称的。

这里的定义配合Matlab做fft实际效果。

):

F(v)=1N∑x=1Nf(x)ei2πvxN,v=1,2,...,N

相同我们能够依据iDFT的定义推演iFFT的算法,其迭代版本号的Matlab实现例如以下:

function [ ifft_m ] = IterativeIFFT( vec )
clear i;
n = length(vec);
ifft_m = BitReverseCopy(vec);
for s = 1 : log2(n)
m = power(2, s);
wm = exp(2 * pi * i / m); for k = 0 : m : n - 1
w = 1;
for j = 0 : m / 2 - 1
t = w * ifft_m(k + j + m / 2 + 1);
u = ifft_m(k + j + 1);
ifft_m(k + j + 1) = u + t;
ifft_m(k + j + m / 2 + 1) = u - t;
w = w * wm;
end
end
end
ifft_m = ifft_m ./ n;
end

(2)二维逆FFT

二维逆FFT和二维FFT的思路一致,对全部行和列分别作一次iFFT就可以:

function [ mifft2 ] = JCGuoIFFT2( data )
h = size(data, 1);
w = size(data, 2);
mifft2 = data; if power(2, log2(h)) ~= h || power(2, log2(w)) ~= w
disp('JCGuoIFFT2 exit: h and w must be the power of 2!')
else
for i = 1 : h
mifft2(i, :) = IterativeIFFT(mifft2(i, :));
end for j = 1 : w
mifft2(:, j) = IterativeIFFT(mifft2(:, j));
end
end
end

(3)逆FFT结果

对之前Rect1.bmp用JCGuoFFT2变换的到的Fourier变换(非shift和log之后、非仅幅度部分)作FFT2逆变换能够直接得到原图像:

这幅图有多个结果。能够看title知道每一个结果的含义,图2-1是用JCGuoIFFT2做傅立叶反变换的结果,得到的图像和原图像、和Matlab ifft2反变换后的图像都是一致的。


5.幅频特性与相频特性

(1)对振幅和相位单独做逆FFT

假设我们仅仅把图像Fourier变换的振幅部分和相位部分单独做二维逆FFT。能够直观的感受人眼对图像幅频特性和相频特性的敏感度。

复数z=a+ib的幅度/振幅定义为:

|z|=a2+b2‾‾‾‾‾‾‾√

相位角和相位定义为:

ϕ(z)=arctanbaeiϕ(z)=eiarctanba

对相位反变换须要在乘以一个系数(我是调出来的。针对图像。肯定能够自己主动的做均衡化):

pic2_fft_angle = angle(pic2_fft);
clear i;
tmp = 10000 * exp(i * pic2_fft_angle);
pic2_ifft_angle = uint8(JCGuoIFFT2(tmp));

对振幅和相位单独做逆FFT结果例如以下:

(2)人眼敏感度

观察上图。幅频特性主要涵盖了图像颜色的分布,相频特性主要刻画了图像的边界信息。人眼对图像的相频特性更加敏感,看相频特性能够大概知道图像内容。


6.Fourier变换的旋转定理

(1)Fourier变换旋转定理

将f(x,y)旋转角度θ0,其Fourier变换F(u,v)也旋转角度θ0

(2)结果

Rect2.bmp是Rect1.bmp旋转45度的示意图(注:原Rect2.bmp是二值的,做了预处理,但其本身边界不平滑。导致效果不太好。但不影响观察旋转定理):

我们能够看到幅度FFT正变换和相位FFT你变换都是旋转了45度,可是幅度FFT逆变换差别较大。


Matlab图像处理系列4———图像傅立叶变换与反变换的更多相关文章

  1. Win8 Metro(C#)数字图像处理--2.53图像傅立叶变换

    原文:Win8 Metro(C#)数字图像处理--2.53图像傅立叶变换  [函数名称] 1,一维FFT变换函数         Complex[] FFT(Complex[] sourceDat ...

  2. Matlab图像处理系列2———空间域平滑滤波器

    注:本系列来自于图像处理课程实验,用Matlab实现最主要的图像处理算法 本文章是Matlab图像处理系列的第二篇文章.介绍了空间域图像处理最主要的概念----模版和滤波器,给出了均值滤波起和中值滤波 ...

  3. Matlab图像处理系列4———傅立叶变换和反变换的图像

    注意:这一系列实验的图像处理程序,使用Matlab实现最重要的图像处理算法 1.Fourier兑换 (1)频域增强 除了在空间域内能够加工处理图像以外,我们还能够将图像变换到其它空间后进行处理.这些方 ...

  4. Matlab图像处理系列1———线性变换和直方图均衡

    注:本系列来自于图像处理课程实验,用Matlab实现最主要的图像处理算法 图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境.灰度线性变换和灰度拉伸是对像素灰度值的变换操 ...

  5. Win8Metro(C#)数字图像处理--2.33图像非线性变换

    原文:Win8Metro(C#)数字图像处理--2.33图像非线性变换  [函数名称] 图像非线性变换函数NonlinearTransformProcess(WriteableBitmap src ...

  6. 为什么要进行傅立叶变换?傅立叶变换究竟有何意义?如何用Matlab实现快速傅立叶变换

    写在最前面:本文是我阅读了多篇相关文章后对它们进行分析重组整合而得,绝大部分内容非我所原创.在此向多位原创作者致敬!!!一.傅立叶变换的由来关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶 ...

  7. 离散傅立叶变换与快速傅立叶变换(DFT与FFT)

    自从去年下半年接触三维重构以来,听得最多的词就是傅立叶变换,后来了解到这个变换在图像处理里面也是重点中的重点. 本身自己基于高数知识的理解是傅立叶变换是将一个函数变为一堆正余弦函数的和的变换.而图像处 ...

  8. MATLAB数字图像处理(一)基础操作和傅立叶变换

    数字图像处理是一门集计算机科学.光学.数学.物理学等多学科的综合科学.随着计算机科学的发展,数字图像处理技术取得了巨大的进展,呈现出强大的生命力,已经在多种领域取得了大量的应用,推动了社会的发展.其中 ...

  9. 数字图像处理-基于matlab-直方图均匀化,傅立叶变换,图像平滑,图像锐化

    直方图均匀化 任务:用MATLAB或VC或Delphi等实现图像直方图均匀化的算法. clc;clear;close all; % 清除工作台 % path(path,'..\pics'); % 设置 ...

随机推荐

  1. Flask设置配置文件

    Flask修改配置: from flask import Flask app = Flask(__name__) app.config['DEBUG'] = True @app.route('/') ...

  2. 洛谷 P2026 求一次函数解析式

    P2026 求一次函数解析式 题目背景 做数学寒假作业的怨念…… 题目描述 给定两个整点的坐标,求它们所在直线的函数解析式(一次函数). 输入输出格式 输入格式: 输入共两行. 第一行有两个整数x1, ...

  3. jquery中prop()和attr()的使用

    jquery1.6+出现的prop()方法. • 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. • 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. • ...

  4. setAttribute的浏览器兼容性

    1.element要用getElementById 或者是ByTagName来得到 2.setAttribute("class", vName)中class是指改变"cl ...

  5. Oracle学习总结(9)—— Oracle 常用的基本操作

    创建用户,相当于在sqlServer中创建一个数据库  create user 用户名 identified by 密码  修改用户密码  alter user 用户名 identified by 新 ...

  6. 忍者无敌-实例解说Cocos2d-x瓦片地图

    实例比較简单,如图所看到的,地图上有一个忍者精灵,玩家点击他周围的上.下.左.右,他能够向这个方向行走. 当他遇到障碍物后是无法穿越的,障碍物是除了草地以为部分,包含了:树.山.河流等. 忍者实例地图 ...

  7. Codeforces Round #450 (Div. 2) D.Unusual Sequences (数学)

    题目链接: http://codeforces.com/contest/900/problem/D 题意: 给你 \(x\) 和 \(y\),让你求同时满足这两个条件的序列的个数: \(a_1, a_ ...

  8. spyder结束死循环的方法

    Ctrl+C 用这个有时候也是不行的,因为如果一直有图片在闪,那么就是直接关了吧 之前记错了一直用ctrl+x不行 导致崩溃,不能重启spyder 但是没有敢再试

  9. HttpWatch--简介及使用技巧

    一 概述: HttpWatch强大的网页数据分析工具.集成在Internet Explorer工具栏.包括网页摘要.Cookies管理.缓存管理.消息头发送/接受.字符查询.POST 数据和目录管理功 ...

  10. js进阶 12-17 jquery实现鼠标左键按下拖拽功能

    js进阶 12-17 jquery实现鼠标左键按下拖拽功能 一.总结 一句话总结:监听的对象必须是文档,鼠标按下运行mousemove事件,鼠标松开取消mousemove事件的绑定,div的偏移的话是 ...