lemonHe

主要关注FPGA信号处理和数字图像处理技术,欢迎交流 邮箱:heliminlemon@163.com

高斯滤波matlab及FPGA实现

1
阅读(6719)

    高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程。通俗的讲,高斯滤波就是对整幅图像进行加权平均的过程,每一个像素点的值,都由其本身和邻域内的其他像素值经过加权平均后得到。

    高斯滤波器使用模块确定的领域内像素的加权平均值代替图像中的每个像素的值,这种处理的降低了图像灰度的剧烈变化,由于典型的随机噪声表现为灰度的急剧变化,因此,使用这种加权平均的滤波器的结果就是降低噪声,当然,这种处理必然会模糊图像边缘、轮廓。一般这种滤波器在应用过程中都使用“滑窗”的方式来实现,高斯滤波的具体操作是:用一个模板(或称卷积、掩模)扫描图像中的每一个像素,用模板确定的邻域内像素的加权平均灰度值去替代模板中心像素点的值。

    由于高斯噪声服从正态分布,一幅受高斯噪声污染的图像各个像素值与原值的偏离程序总体上符合正态分布,下面上一种经典的高斯滤波掩膜,随着高斯噪声方差的变化,掩膜内系数需做相应调整。

                                                    1    2    1

                                                    2    4    2

                                                    1    2    1



sigma = 0.5;
image    Matlab中有现成的高斯滤波函数,先调用fspecial生成滤波器,再调用imfilter,并使用滤波器,即可完成滤波。

gaussFilter = fspecial('gaussian',[5 5],sigma);
ImGauss=imfilter(im1,gaussFilter,'replicate');
imshow(ImGauss);

    但对于FPGA析级代码来说,需要自己写滤波器,通常使用移位寄存器来生成,编写自适应滤波难度太大,我也没有试过,固定系数的滤波器实现起来倒是比较方便,在板级实现前,先做个matlab仿真。

    代码如下:

clc;
clear all;
close all;
im1 = imread('lena_gray.tif');      %原始图像
[m,n] = size(im1);
im2 = uint16(zeros(m,n));           %定义一滤波后图像
im3 = uint16(im1);                  %转换到16bit
%为了实现对边缘的滤波,对图像进行扩展
im1_mid1 = uint16(zeros(m+2,n+2));  
im1_mid1(2:m+1,2:n+1) = im3;
im1_mid1(1,2:n+1) = im1_mid1(3,2:n+1);
im1_mid1(m+2,2:n+1) = im1_mid1(m,2:n+1);
im1_mid1(1:m+2,1) = im1_mid1(1:m+2,3);
im1_mid1(1:m+2,n+2) = im1_mid1(1:m+2,n+2);
%为了实现对边缘的滤波,对图像进行扩展
%掩模
%   1   2   1
%   2   4   2
%   1   2   1
for i=2:1:m+1
    for j=2:1:n+1
        im2(i-1,j-1) = (im1_mid1(i-1,j-1)+2*im1_mid1(i-1,j)+im1_mid1(i-1,j+1)...
            +2*im1_mid1(i,j-1)+4*im1_mid1(i,j)+2*im1_mid1(i,j+1)+im1_mid1(i+1,j-1)...
            +2*im1_mid1(i+1,j)+im1_mid1(i+1,j+1))/16;
    end
end
subplot(1,2,1);
imshow(im1);
title('滤波前原始图像');
subplot(1,2,2);
imshow(uint8(im2));
title('滤波后图像');

    图像平滑效果如下图所示,右图为高斯滤波后的效果图,还是能看到图像变模糊了的。

image

    图像去噪效果如下图所示,左图为添加了高斯噪声的图像,右图为高斯去噪后的图像,效果不明显,但还是有。

image

    对于滑窗方式的计算,在FPGA实现时往往使用移位寄存器来实现,一般选择3个tap,由于我的图像位宽为14bit,每行数据为320个像素,在配置shift register时设置如下。

image

image

    配置好后,正常工作时,移位寄存器将同时输出3行的数据,进行如下操作即可得到滤波后像素值,由于掩模系数为1,2,4,所以在操作时分别保留原值、左移1位、左移两位即可,最后再右移4位(除以16)就可以得到滤波后的结果,这种方法在FPGA中很好实现。

image

    对于均值滤波器这类的线性平滑滤波器,在FPGA实现上与gauss滤波器很类似,也可用这种滑窗方式实现。