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

我在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情况下定义高斯滤波器并将其应用于图像?

参考资料:
Stack Overflow
收藏
评论
共 1 个回答
高赞 时间 活跃

真的很不幸,您不能使用“图像处理工具箱”中的某些内置方法来帮助您完成此任务。但是,我们仍然可以按照您的要求进行操作,尽管会有些困难。我仍将使用IPT中的一些功能来帮助我们完成您所要求的。另外,我将假设您的图像是灰度的 。如果您要对彩色图像执行此操作,我会把它留给您。


创建高斯蒙版

您可以做的是使用meshgrid创建2D空间坐标的网格,该网格的大小与您要创建的高斯滤镜的大小相同。我将假设N为奇数会使我的生活更轻松。这将使整个蒙版周围的空间坐标对称。

如果您还记得,二维高斯可以定义为:

指数前面的缩放因子主要与确保高斯下面的面积为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复制到尽可能多的列中,以创建...让我们称其为高斯矩阵,因为它缺少更好的术语。使用这个高斯矩阵,我们将对该矩阵和im2col的输出进行im2col元素乘法。完成此操作后,我们可以汇总每一列的所有行。进行逐元素乘法的最好方法是通过bsxfun ,我将向您展示如何使用它。

这样的结果将是您过滤的图像,但是它将是单个矢量。您将需要使用col2im将矢量重新col2im为矩阵形式,以获取过滤后的图像。但是,这种方法的一个小问题是,它不会过滤空间遮罩超出图像尺寸的像素。因此,您实际上需要用零填充图片的边框,以便我们可以正确地进行过滤。我们可以使用padarray做到这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系统路径的一部分。通过使用以上参数以及图像,这就是我们得到的输入和输出图像:

在此处输入图片说明

在此处输入图片说明

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号