傅里叶变换

Question:

实现一个函数来完成 2 维离散傅里叶变换和反变换(DFT 和 IDFT)。函数格式为“dft2d (input_img,flags) → output_img”,该函数返回 DFT / IDFT 的结果。“flags”是一个参数,用于指定 DFT 或IDFT。如有需要,你可以修改该函数的格式。请载入你的输入图像,用你的程序来完成:

1. 对输入图像做离散傅里叶变换(DFT),并且把中心化后的傅里叶频谱粘贴到报告里。

2. 对上一个问题的结果做离散傅里叶反变换(IDFT),并把实部粘贴到报告里。 注意:实部与输入图像非常相似。

3. 详细描述你是如何实现 DFT / IDFT 的,也就是说,针对“dft2d”函数进行算法说明,字数不能超过两页。请集中在算法方面,不要简单地复制/粘贴代码。

Answer:

function [temp3] = dft2d(I,flag)
%读取原图像
if isstr(I)
    img = imread(I);
end
[M,N] = size(img); %取出图像高度和宽度
temp1=double(img);%将矩阵转为浮点型便于计算
temp=temp1;
s = 0;
%中心化
if (flag == 0) 
    for x=1:M
        for y=1:N
            if rem(x+y,2)
                temp1(x,y) = -temp1(x,y);
            end
        end
    end
end
%傅里叶变换,采用的是将二维DFT转为两个一维DFT
%变换的第一部分,temp2为中间变量矩阵
for x=1:M
    for v=1:N
        for y=1:N
            s = s + temp1(x,y) * exp((-1i) * 2 * pi * v * y / N);
        end
        temp2(x,v) = s;
        s = 0;
    end
end
%变换的第二部分,temp为未进行中心化的生成矩阵,temp3为中心化后并通过傅里叶变换产生的频谱图
for u=1:M
    for v=1:N
        for x=1:M
            s = s + temp2(x,v) * exp((-1i) * 2 * pi * u * x / M);
        end
        temp(u,v) = s;
        temp3(u,v) = log(abs(s));
        s = 0;
    end
end
%对频谱图标定
if (flag == 0)
    max = 0;
    for u=1:M
        for v=1:N
            if (temp3(u,v) > max)
                max = temp3(u,v);
            end
        end
    end
    scale = 256/max;
    for u=1:M
        for v=1:N
            temp3(u,v) = temp3(u,v) * scale;
        end
    end
    figure
    subplot(221)
    imshow(img)%显示原图像
    axis on
    title(['原图像']);
    subplot(222)
    %imshow(temp3,[])
    imshow(uint8(temp3))
    axis on
    title(['傅里叶变换']);
end
%作傅里叶反变换,方法跟傅里叶正变换一样,都是采用二维转一维
if (flag == 1)
for u=1:M
    for y=1:N
        for v=1:N
            s = s + temp(u,v) * exp((1i) * 2 * pi * v * y / N);
        end
        temp4(u,y) = s;
        s = 0;
    end
end

for x=1:M
    for y=1:N
        for u=1:M
            s = s + temp4(u,y) * exp((1i) * 2 * pi * u * x / M) / M;
        end
        temp5(x,y) = real(s); %temp5为反变换后的矩阵
        s = 0;
    end
end
%标定
max = 0;
for u=1:M
    for v=1:N
        if (temp5(u,v) > max)
            max = temp5(u,v);
        end
    end
end
scale = 256/max;
for u=1:M
    for v=1:N
        temp5(u,v) = temp5(u,v) * scale;
    end
end
figure
subplot(221)
imshow(img)%显示原图像
axis on
title(['原图像']);
subplot(222)
%imshow(temp5,[])%显示反变换图像
imshow(uint8(temp5))
axis on
title(['反变换图像']);
end

Algorithm description:

傅里叶正变换和反变换都是采用一样的方法,就是利用二维 DFT 的可分性,将二维变
换转为一维变换。按照书本所给公式,实现两个三重循环即可。公式如下:

代码实现如下:
傅里叶正变换:
%傅里叶变换,采用的是将二维 DFT 转为两个一维 DFT
%变换的第一部分,temp2 为中间变量矩阵
for x=1:M
for v=1:N
for y=1:N
s = s + temp1(x,y) * exp((-1i) * 2 * pi * v * y / N);
end
temp2(x,v) = s;
s = 0;
end
end
%变换的第二部分,temp 为未进行中心化的生成矩阵,temp3 为中心化后并通过傅里叶变换产
生的频谱图
for u=1:M
for v=1:N
for x=1:M
s = s + temp2(x,v) * exp((-1i) * 2 * pi * u * x / M);
end
temp(u,v) = s;
temp3(u,v) = log(abs(s));
s = 0;
end
End
傅里叶反变换:
%作傅里叶反变换,方法跟傅里叶正变换一样,都是采用二维转一维
if (flag == 1)
for u=1:M
for y=1:N
for v=1:N
s = s + temp(u,v) * exp((1i) * 2 * pi * v * y / N);
end
temp4(u,y) = s;
s = 0;
end
end
for x=1:M
for y=1:N
for u=1:M
s = s + temp4(u,y) * exp((1i) * 2 * pi * u * x / M) / M;
end
temp5(x,y) = real(s); %temp5 为反变换后的矩阵
s = 0;
end
end

猜你喜欢

转载自blog.csdn.net/qq_34200964/article/details/79519289