如何在不使用fspecial,imfilter或conv2的情况下在MATLAB中创建和应用高斯滤波器?

时间:2014-12-16 06:49:26

标签: matlab image-processing

我在MATLAB中有以下代码:

I=imread(image);
h=fspecial('gaussian',si,sigma);
I=im2double(I);
I=imfilter(I,h,'conv');
figure,imagesc(I),impixelinfo,title('Original Image after Convolving with gaussian'),colormap('gray');

如何在没有imfilterfspecialconv2的图片中定义和应用高斯滤镜?

1 个答案:

答案 0 :(得分:24)

非常不幸的是,您无法使用图像处理工具箱中的某些内置方法来帮助您完成此任务。但是,我们仍然可以做你要求的事情,尽管这会有点困难。我仍然会使用IPT中的某些功能来帮助我们按照您的要求进行操作。此外,我将假设您的图像是灰度。如果您想为彩色图像执行此操作,我会留给您。


创建高斯蒙版

您可以使用meshgrid创建一个2D空间坐标网格,其大小与您正在创建的高斯滤镜遮罩相同。我会假设N很奇怪,让我的生活更轻松。这将允许空间坐标在掩模周围对称。

如果你还记得,2D高斯可以定义为:

指数前面的比例因子主要是确保高斯下面的区域是1.我们将以另一种方式处理这种归一化,我们生成高斯系数而不缩放因子,然后简单地总结掩码中的所有系数,并将每个元素除以该总和以确保单位面积。

假设您要创建N x N过滤器,并且使用给定的标准差sigma,则代码看起来像这样,h表示高斯过滤器。

%// Generate horizontal and vertical co-ordinates, where
%// the origin is in the middle
ind = -floor(N/2) : floor(N/2);
[X Y] = meshgrid(ind, ind);

%// Create Gaussian Mask
h = exp(-(X.^2 + Y.^2) / (2*sigma*sigma));

%// Normalize so that total area (sum of all weights) is 1
h = h / sum(h(:));

如果您使用fspecial进行检查,对于N的奇数值,您会看到面具匹配。


过滤图像

过滤图像背后的基础是输入图像中的每个像素,您采用围绕此像素的像素邻域,该像素与高斯蒙版的大小相同。您使用高斯蒙版对此像素邻域执行逐元素乘法,并将所有元素汇总在一起。结果和是输出像素在输出图像中的相应空间位置处的结果。我将使用im2col来获取像素邻域并将其转换为列。 im2col将获取每个列并创建一个矩阵,其中每列代表一个像素邻域。

接下来我们可以做的是将高斯蒙板和转换这个转换为列向量。接下来,我们将采用此列向量,并根据im2col的结果将其复制为尽可能多的列以创建...让我们称之为高斯矩阵,因为缺少更好的术语。使用这个高斯矩阵,我们将使用此矩阵和im2col的输出进行逐元素乘法。一旦我们这样做,我们可以总结每列的所有行。逐个元素乘法的最佳方法是bsxfun,我将尽快向您展示如何使用它。

这将是您的过滤图像,但它将是一个矢量。您需要使用col2im将此向量重新整形为矩阵形式,以获取滤镜图像。然而,这种方法的一个小问题是它不会过滤空间掩模超出图像尺寸的像素。因此,您实际上需要用零填充图像的边框,以便我们可以正确地执行过滤器。我们可以使用padarray执行此操作。

因此,我们的代码看起来像这样,与您在上面定义的变量一起使用:

N = 5; %// Define size of Gaussian mask
sigma = 2; %// Define sigma here

%// Generate Gaussian mask
ind = -floor(N/2) : floor(N/2);
[X Y] = meshgrid(ind, ind);
h = exp(-(X.^2 + Y.^2) / (2*sigma*sigma));
h = h / sum(h(:));

%// Convert filter into a column vector
h = h(:);

%// Filter our image
I = imread(image);
I = im2double(I);
I_pad = padarray(I, [floor(N/2) floor(N/2)]);
C = im2col(I_pad, [N N], 'sliding');
C_filter = sum(bsxfun(@times, C, h), 1);
out = col2im(C_filter, [N N], size(I_pad), 'sliding');

out包含将高斯过滤蒙版应用于输入图像I后的过滤图像。例如,让我们说N = 9, sigma = 4。我们还使用cameraman.tif,它是MATLAB系统路径的一部分图像。通过使用上述参数以及图像,这是我们得到的输入和输出图像:

enter image description here

enter image description here