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

摘要:
注:这一系列实验的图像处理程序使用Matlab来实现最重要的图像处理算法1.傅里叶变换频域增强可以在空间域中处理图像,我们也可以将图像转换到其他空间进行处理。这些方法称为变换域方法,最常见的变换域是频域。在Matlab中编写时,有必要考虑映射关系cleari,以避免变量i和复杂符号i之间的混淆。很明显,Matlabworkspace中的缓存默认vec是双类型的。Matlab提供fftshift函数来完成翻译。这里的定义与Matlab配合,以实现fft的实际效果。

注意:这一系列实验的图像处理程序,使用Matlab实现最重要的图像处理算法


1.Fourier兑换

(1)频域增强

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

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

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


2.FFT算法

(1)离散Fourier变换,DFT

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

F(v)=x=1Nf(x)ei2π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=1Ny=1Nf(x,y)ei2π(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)ei2πvyN,v=1,2,...,N

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

F(u,v)=x=1NF(x,v)ei2π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)=1Nx=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)θ0FourierF(u,v)θ0

(2)结果

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

这里写图片描写叙述

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


免责声明:文章转载自《Matlab图像处理系列4———傅立叶变换和反变换的图像》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Android 手动显示和隐藏软键盘单节点部署OpenStack(Queens版本、DevStack)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

用最简单的方式在C#中使用多线程加速耗时的图像处理算法的执行(多核机器)。

图像处理中,有很多算法由于其内在的复杂性是天然的耗时大户,加之图像本身蕴涵的数据量比一般的对象就大,因此,针对这类算法,执行速度的提在很大程度上依赖于硬件的性能,现在流行的CPU都是至少2核的,稍微好点的4核,甚至8核,因此,如果能充分利用这些资源,必将能发挥机器的强大优势,为算法的执行效果提升一个档次。 在单核时代,多线程程序的主要目的是防止UI假死,而...

matlab中figure 创建图窗窗口

语法 figure figure(Name,Value) f = figure(___) figure(f) figure(n) 说明 figure 使用默认属性值创建一个新的图窗窗口。生成的图窗为当前图窗。 示例 figure(Name,Value) 使用一个或多个名称-值对组参数修改图窗的属性。例如,figure('Color...

matlab学习:人脸识别之PCA( Principal Component Analysis )

1.链接推荐 关于理解PCA的推荐链接:http://www.cnblogs.com/LeftNotEasy/archive/2011/01/08/lda-and-pca-machine-learning.html 关于理解SVD的推荐链接:http://www.cnblogs.com/LeftNotEasy/archive/2011/01/19/svd-...

【MATLAB】matlab 中去掉向量中重复数字并且不改变原顺序

1、首先我们可以使用 unique 去掉向量中的重复数字。 a = [374 3 375 41 1 415 3 208 41 373 415 1 208 2 373 206 2]; b = unique(a); 其中: b = [1 2 3 41 206 208 373 374 375 415] 我们发现,matlab 中的 unique 函数对去重后...

MATLAB拟合和插值

定义 插值和拟合: 曲线拟合是指您拥有散点数据集并找到最适合数据一般形状的线(或曲线)。 插值是指您有两个数据点并想知道两者之间的值是什么。中间的一半是他们的平均值,但如果你只想知道两者之间的四分之一,你必须插值。   拟合 我们着手写一个线性方程图的拟合: y=3x^3+2x^2+x+2 首先我们生成一组数据来分析: x=-5:0.5:5; e=50*r...

MATLAB2017 下载及安装教程

全文借鉴于软件安装管家  链接: https://pan.baidu.com/s/1-X1Hg35bDG1G1AX4MnHxnA 提取码: ri88 复制这段内容后打开百度网盘手机App,操作更方便哦 先打开百度网盘下载 安装步骤: 1.完整的安装包应该有13个压缩包,必须全部下载才能解压。 2.右击“thMWoMaR17a.part01.rar”文件...