频域率滤波

Question:

实现一个函数来完成频率域滤波。函数格式是“filter2d_freq(input_img, filter) → output_img”, 这里的“filter”是给定的滤波器。如有需要,可以修改函数格式。根据卷积定理,你需要对给定的图片和滤4波器做离散傅里叶变换/快速傅里叶变换 (DFT / FFT),然后将他们乘起来,最后做离散傅里叶反变换/快速傅里叶反变换来获得滤波结果。因此,基于“dft2d”(或者“fft2d”)来实现“filter2d_freq”应该是比较简单的。当然,你需要注意一些细节,比如缠绕误差(wraparound error)(参加书本的第 4.7节)请载入你的输入图像,用你的程序"filter2d_freq"来完成:

1. 分别用 3 x 3,7 x 7 和 11 x 11 的均值滤波器来平滑你输入的图像,将相应的三个输出结果粘贴到报告里。

2. 用 3 x 3 的拉普拉斯滤波器来锐化你输入的图像(本上有 4 种拉普拉斯滤波器,参见图3.37,你可以使用其中任意一种),并将输出结果放在报告中。

3. 详细描述你是如何实现滤波操作的,也就是说,针对“filter2d_freq”函数进行算法说明,字数不能超过两页。

Answer:

function filter2d_freq(I,filter)
%读取原图像
if isstr(I)
    img = imread(I);
end
[M,N] = size(img); %取出图像高度和宽度
[m,n] = size(filter); %取出滤波器高度和宽度
ori = double(img);
% 0填充图像矩阵和滤波器
P = 2*M;
Q = 2*N;
f = zeros(P,Q);
h = zeros(P,Q);
f(1:M,1:N) = img;
f(M+1:P,1:Q) = 0;
f(1:M,N+1:Q) = 0;
h(1:m,1:n) = filter;
h(m+1:P,1:Q) = 0;
h(1:m,n+1:Q) = 0;
f1 = double(f); %转为double类型便于计算
h1 = double(h);
s = 0;
h = 0;
%中心化图像和滤波器
for x=1:P
    for y=1:Q
        if rem(x+y,2)
           f1(x,y) = -f1(x,y);
           h1(x,y) = -h1(x,y);
        end
    end
end
%作图像和滤波器的傅里叶变化
for x=1:P
    for v=1:Q
        for y=1:Q
            s = s + f1(x,y) * exp((-1i) * 2 * pi * v * y / Q);
            h = h + h1(x,y) * exp((-1i) * 2 * pi * v * y / Q);
        end
        f2(x,v) = s;
        h2(x,v) = h;
        s = 0;
        h = 0;
    end
end
for u=1:P
    for v=1:Q
        for x=1:P
            s = s + f2(x,v) * exp((-1i) * 2 * pi * u * x / P);
            h = h + h2(x,v) * exp((-1i) * 2 * pi * u * x / P);
        end
        F(u,v) = s;
        H(u,v) = h;
        s = 0;
        h = 0;
    end
end
%作频率域乘积
for u=1:P
    for v=1:Q
        G(u,v) = H(u,v) * F(u,v);
    end
end
%作图像和滤波器的傅里叶反变换
for u=1:P
    for y=1:Q
        for v=1:Q
            s = s + G(u,v) * exp((1i) * 2 * pi * v * y / Q);
        end
        g1(u,y) = s;
        s = 0;
    end
end
for x=1:P
    for y=1:Q
        for u=1:P
            s = s + g1(u,y) * exp((1i) * 2 * pi * u * x / P) / P;
        end
        g2(x,y) = real(s); %取实部
        s = 0;
    end
end
%再次中心化
for x=1:P
    for y=1:Q
        if rem(x+y,2)
           g2(x,y) = -g2(x,y);
        end
    end
end
%截取M*N大小矩阵
for x=1:M
    for y=1:N
        g(x,y) = g2(x,y);
    end
end
%输出结果
figure
subplot(221)
imshow(img)%显示原图像
axis on
title(['原图像']);
max = 0;
for u=1:M
    for v=1:N
        if (g(u,v) > max)
            max = g(u,v);
        end
    end
end
scale = 256/max;
for u=1:M
    for v=1:N
        g(u,v) = g(u,v) * scale;
    end
end
%g = ori - g; 拉普拉斯算子使用该公式;如果算子中间像素为正数,请把‘-’变‘+’;
subplot(222)
imshow(uint8(g))%显示滤波后图像;
axis on
title(['滤波后图像']);

Algorithm description:

我是根据书本 4.7.3 节内容按照它所描述的步骤一步步实现频率域滤波算法的。具体步骤
如下:
1. 选择填充参数 P=2M,Q=2N;
2. 对输入图像和滤波器补 0,生成 P*Q 大小的图像矩阵和滤波器;
3. 中心化,用(1)
x y 乘以图像矩阵以及滤波器移到其变换的中心;
4. 计算图像跟滤波器的 DFT,生成 F(u,v)和 H(u,v);
5. 用阵列相乘形成乘积 G(u,v) = H(u,v) * F(u,v);
6. 作傅里叶反变换,公式为:
g(x,y) = {real[Ʒ-1[G(u,v)]]} * (1)
x y
7. 从 g(x,y)的左上限提取 M*N 区域,得到最终处理结果 g(x,y)。
相关代码:
矩阵补 0:
% 0 填充图像矩阵和滤波器
P = 2*M;
Q = 2*N;
f = zeros(P,Q);
h = zeros(P,Q);
f(1:M,1:N) = img;
f(M+1:P,1:Q) = 0;
f(1:M,N+1:Q) = 0;
h(1:m,1:n) = filter;
h(m+1:P,1:Q) = 0;
h(1:m,n+1:Q) = 0;
中心化,傅里叶正变换和反变换跟上一个代码基本类似,就不再附上;
频率域乘积:
%作频率域乘积
for u=1:P
for v=1:Q
G(u,v) = H(u,v) * F(u,v);
end
end
截取 M*N 大小图像作为输出
%截取 M*N 大小矩阵
for x=1:M
for y=1:N
g(x,y) = g2(x,y);
end
end

猜你喜欢

转载自blog.csdn.net/qq_34200964/article/details/79519338
今日推荐