如果您希望在使用高斯核过滤图像后计算每个子图像的平均值,只需将图像与mean or average filter 进行卷积即可。这将收集原始图像中的子图像,并且对于每个输出位置,您将计算平均值。
按照您最初假设掩码大小为 3 x 3,只需将 conv2 与具有所有 1/9 系数的 3 x 3 掩码结合使用即可。换句话说:
%// Your code
%% Given Image I,Defined a Gaussian Kernel
sigma=3;
K=fspecial('gaussian',round(2*sigma)*2+1,sigma);
KI=conv2(I,K,'same');
%// New code
mask = (1/9)*ones(3,3);
out = conv2(KI, mask, 'same');
out 中的每个位置都会为您提供高斯过滤结果中每个 3 x 3 子图像的平均值。
您还可以通过使用 fspecial 和标志 average 并指定掩码的大小/宽度来创建平均掩码。鉴于您已经在代码中使用它,您已经知道它的存在。因此,您也可以这样做:
mask = fspecial('average', 3);
上面的代码假设掩码的宽度和高度相同,因此它将创建一个包含所有 1/9 系数的 3 x 3 掩码。
一边
conv2 专为一般二维信号而设计。如果您要过滤图像,我建议您改用imfilter。您应该可以访问它,因为fspecial 是图像处理工具箱的一部分,imfilter 也是如此。众所周知,imfilter 比conv2 效率更高,并且如果可用,还可以使用Intel Integrated Performance Primitives (Intel IPP)(基本上,如果您在具有支持 IPP 的 Intel 处理器的计算机上运行 MATLAB)。因此,您确实应该以这种方式执行过滤:
%// Your code
%% Given Image I,Defined a Gaussian Kernel
sigma=3;
K=fspecial('gaussian',round(2*sigma)*2+1,sigma);
KI=imfilter(I,K,'replicate'); %// CHANGE
%// New code
mask = fspecial('average', 3);
out = imfilter(KI, mask, 'replicate'); %// CHANGE
replicate 标志用于处理边界条件。当您的遮罩超出原始图像的边界时,replicate 会简单地复制图像每一侧的边框,以便在执行过滤时遮罩可以舒适地适合图像。
编辑
鉴于您的评论,您想要提取在KI 中看到的子图像。您可以使用非常强大的im2col 函数,它是图像处理工具箱的一部分。你这样称呼它:
B = im2col(A,[m n]);
A 将是您的输入图像,B 将是一个大小为mn x L 的矩阵,其中L 将是您的图像中可能存在的子图像的总数,m ,n分别是每个子图像的高度和宽度。 im2col 的工作原理是,对于图像中存在的每个子图像,它会扭曲它们,使其适合B 中的单个 列。因此,B 中的每一列都会生成一个单独的子图像,该子图像会被扭曲成一列。然后,您可以使用 B 中的每一列进行 GMM 建模。
但是,im2col 仅返回不会超出范围的有效子图像。如果您想处理边缘和角落的情况,您需要先填充图像。使用padarray 来促进此填充。因此,要满足您的要求,我们只需:
Apad = padarray(KI, [1 1], 'replicate');
B = im2col(Apad, [3 3]);
第一行代码将填充图像,使图像周围有一个 1 像素的边框。这将允许您在边界位置提取 3 x 3 子图像。我使用replicate 标志,以便您可以简单地复制边框像素。接下来,我们使用im2col,以便您获得 3 x 3 的子图像,然后将其存储在B 中。因此,B 将成为一个 9 x L 矩阵,其中每一列都会为您提供一个 3 x 3 的子图像。
请注意,im2col 会以 column-major 格式扭曲这些列。这意味着对于您拥有的每个子图像,它会获取子图像中的每一列并将它们堆叠在一起,从而为您提供9 x 1 列。您将拥有L 总子图像,这些子图像水平连接以产生9 x L 矩阵。此外,请记住,子图像的读取顺序从上到下,然后从左到右,因为这是 MATLAB 以列优先顺序运行的本质。