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

Dav*_*992 3 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');
Run Code Online (Sandbox Code Playgroud)

我该如何定义和应用高斯滤波器,图像无imfilter,fspecialconv2

ray*_*ica 25

非常不幸的是,您无法使用图像处理工具箱中的某些内置方法来帮助您完成此任务.但是,我们仍然可以按照您的要求进行操作,但这样做会有点困难.我仍然会使用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(:));
Run Code Online (Sandbox Code Playgroud)

如果你选中这个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');
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

在此输入图像描述