如何计算图像 I 中所有子图像的平均值

How to compute the mean value of all sub-imges in image I

我有一个任务是计算从输入图像 I 中提取的子图像的平均值。让我们解释一下我的任务。我有一个图像 I(即 9x9)和一个 window(即尺寸 3x3)。 window 将从图像的左上角到右下角 运行。因此,它将输入图像提取为许多子图像。我想计算这些子图像的平均值。你能给我一些 matlab 代码来计算它吗?

这是我的解决方案。但是没用。

如果您希望在使用高斯核过滤图像后计算每个子图像的平均值,只需将图像与 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 子图像的平均值。

您还可以通过使用带有标志 averagefspecial 并指定掩码的大小/宽度来创建平均掩码。鉴于您已经在您的代码中使用它,您已经知道它的存在。因此,您也可以这样做:

mask = fspecial('average', 3);

以上代码假定掩码的宽度和高度相同,因此它将创建一个所有 1/9 系数的 3 x 3 掩码。

放在一边

conv2是为一般二维信号设计的。如果您要过滤 图像 ,我建议您使用 imfilter instead. You should have access to it, since fspecial is part of the Image Processing Toolbox, and so is imfilter. imfilter is known to be much more efficient than conv2, and also makes use of Intel Integrated Performance Primitives (Intel IPP)(如果可用的话)(基本上如果您在计算机上使用 运行 MATLAB,该计算机具有英特尔处理器支持 IPP)。因此,您确实应该以这种方式执行过滤:

%// 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 仅 returns 个不超出范围的有效子图像。如果你想处理边缘和角落的情况,你需要先 pad 图像。使用 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 的子图像。

请注意 im2colcolumn-major 格式扭曲这些列。这意味着对于您拥有的每个子图像,它会获取子图像中的每一列并将它们堆叠在一起,从而为您提供一个 9 x 1 列。您将拥有 L 总子图像,这些子图像被水平连接以生成 9 x L 矩阵。另外,请记住,子图像是从上到下读取的 ,然后是从左到右,因为这是 MATLAB 按列优先顺序运行的本质。