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

注:本系列来自于图像处理课程实验,用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由于递归栈开销大且容量有限等缺陷(但理解容易),一般计算采取迭代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)无关的部分)具有对称的性质(详见《图像工程(上册)图像处理》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文档发现它是采用第二种方法,对图像做以下子矩阵交换:

那么我们可以很容易的写出自己的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逆变换区别较大。


时间: 2024-10-27 12:17:36

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

图像处理复习2——图像傅立叶变换和频域滤波

图像处理复习 CH4 基本图像变换 4.1 DFT (1)一维DFT 一维DFT: F(u)=1N∑N?1x=0f(x)e?j2πuxN,x=0,1,-,N?1 其逆变换: f(x)=∑N?1u=0F(u)ej2πuxN,u=0,1,-,N?1 (2)二维DFT 二维DFT: F(u,v)=1N∑N?1x=0∑N?1y=0f(x,y)e?j2πux+vyN,u,v=0,1,-,N?1 其逆变换: f(x,y)=1N∑N?1u=0∑N?1v=0F(u,v)ej2πux+vyN,x,y=0,1,-,

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

注:本系列来自于图像处理课程实验,用Matlab实现最基本的图像处理算法 本文章是Matlab图像处理系列的第二篇文章,介绍了空间域图像处理最基本的概念----模版和滤波器,给出了均值滤波起和中值滤波器的Matlab实现,最后简要讨论去躁效果. 1.空间域增强 (1)模版运算 图像处理中,模版可以看作是n*n(n一般是奇数)的窗口,模版连续地运动于整个图像中,对模版窗口范围内的像素做相应处理. 模版运算主要分为: 模版卷积 模版排序 模版卷积是把模版内像素的灰度值和模版中对应的灰度值相乘,求平均

图像处理之基础---卷积傅立叶变换中的复数

整个看FFT过程中复数一直很折磨我. 原本的实数的东西通过复数表达很像旋转矩阵用quaternion来表达,尽管旋转vector还是要用matrix来做,但是通过用quaternion表达的旋转意义可以做插值等很多快速的操作,而且内存消耗也小,在做完这些操作之后再转成matrix用就好了. 复数表达也是类似. a+bi = M*(cos(theta)+sin(theta)*i)----极坐标 cos(x) + sin(x)*i = exp(x*i)----欧拉公式 这个用欧拉公式转出来的exp(

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

注:本系列来自于图像处理课程实验,用Matlab实现最基本的图像处理算法 图像点处理是图像处理系列的基础,主要用于让我们熟悉Matlab图像处理的编程环境.灰度线性变换和灰度拉伸是对像素灰度值的变换操作,直方图是对像素灰度值的统计,直方图均衡是对灰度值分布的变换. 1.灰度线性变换 (1)线性变换函数 原图向灰度值为g,通过线性函数f(x)=kx+b转换为f(g)得到灰度的线性变换. (2)代码实现 Matlab中支持矩阵作为函数参数传入,定义一个线性转换函数,利用Matlab矩阵操作,用一行代

Matlab图像处理系列3———空间域锐化滤波器

注:本系列来自于图像处理课程实验,用Matlab实现最基本的图像处理算法 1.锐化滤波器 锐化滤波,是将图像的低频部分减弱或去除,保留图像的高频部分,即图像的边缘信息. 图像的边缘.轮廓一般位于灰度突变的地方,也就是图像的高频部分,通常用灰度差分提取边缘轮廓. 图像中边缘轮廓通常是任意方向的,因此我们的差分运算需要具有方向性.各向同性的边缘检测算子对任意方向的边缘轮廓都有相同的检测能力,那么什么是算子? 算子是一个函数空间到函数空间上的映射O:X→X.广义上的算子可以推广到任何空间,如内积空间等

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

写在最前面:本文是我阅读了多篇相关文章后对它们进行分析重组整合而得,绝大部分内容非我所原创.在此向多位原创作者致敬!!! 一.傅立叶变换的由来 关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶变换的描述,但是大都是些故弄玄虚的文章,太过抽象,尽是一些让人看了就望而生畏的公式的罗列,让人很难能够从感性上得到理解,最近,我偶尔从网上看到一个关于数字信号处理的电子书籍,是一个叫Steven W. Smith, Ph.D.外国人写的,写得非常浅显,里面有七章由浅入深地专门讲述关于离散信号的傅

傅立叶变换的物理意义

1.为什么要进行傅里叶变换,其物理意义是什么? 傅立叶变换是数字信号处理领域一种很重要的算法.要知道傅立叶变换算法的意义,首先要了解傅立叶原理的意义.傅立叶原理表明:任何连续测量的时序或信号,都可以表示为不同频率的正弦波信号的无限叠加.而根据该原理创立的傅立叶变换算法利用直接测量到的原始信号,以累加方式来计算该信号中不同正弦波信号的频率.振幅和相位. 和傅立叶变换算法对应的是反傅立叶变换算法.该反变换从本质上说也是一种累加处理,这样就可以将单独改变的正弦波信号转换成一个信号. 因此,可以说,傅立

傅立叶变换

傅立叶变换是数字信号处理领域一种很重要的算法.要知道傅立叶变换算法的意义,首先要了解傅立叶原理的意义.傅立叶原理表明:任何连续测量的时序或信号,都可以表示为不同频率的正弦波信号的无限叠加.而根据该原理创立的傅立叶变换算法利用直接测量到的原始信号,以累加方式来计算该信号中不同正弦波信号的频率.振幅和相位.和傅立叶变换算法对应的是反傅立叶变换算法.该反变换从本质上说也是一种累加处理,这样就可以将单独改变的正弦波信号转换成一个信号.因此,可以说,傅立叶变换将原来难以处理的时域信号转换成了易于分析的频域

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

数字图像处理是一门集计算机科学.光学.数学.物理学等多学科的综合科学.随着计算机科学的发展,数字图像处理技术取得了巨大的进展,呈现出强大的生命力,已经在多种领域取得了大量的应用,推动了社会的发展.其中,遥感领域中,对于影像数据的处理均基于数字图像处理的技术.而遥感影像数据作为地理信息科学的重要数据源,如何从中获取有用的信息,是地理信息数据处理中重要的内容. MATLAB作为数学领域应用最广泛的一种软件,集成了对于图片处理的函数和功能,成为了处理数字图像问题的佼佼者.其出众的计算能力和简便的绘图能