很遗憾,您不能使用图像处理工具箱中的一些内置方法来帮助您完成这项任务。但是,我们仍然可以按照您的要求进行操作,尽管会有些困难。我仍将使用 IPT 中的一些功能来帮助我们完成您的要求。另外,我将假设您的图像是灰度。如果您想为彩色图像执行此操作,我将留给您。
创建高斯蒙版
您可以使用meshgrid 创建一个二维空间坐标网格,该网格与您正在创建的高斯滤镜蒙版大小相同。我将假设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 的输出进行逐个元素的乘法。一旦我们这样做了,我们就可以对每一列的所有行求和。进行这种逐个元素相乘的最佳方法是通过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 系统路径的一部分。通过使用上述参数,以及图像,这是我们得到的输入和输出图像: