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

时间:2015-02-05 18:35:10

标签: matlab image-processing

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

这是我的解决方案。但它不起作用。

  • 首先,我将窗口定义为高斯
  • 其次,高斯函数将使用卷积函数从左上角到右下角运行。 (注意,它必须使用高斯内核)
  • 计算每个子窗口的平均值

    %% Given Image I,Defined a Gaussian Kernel
    sigma=3;
    K=fspecial('gaussian',round(2*sigma)*2+1,sigma);     
    KI=conv2(I,K,'same');
    %% mean value
    mean(KI)
    

    这里的问题是关闭所有子图像的平均值将具有与图像I相似的尺寸。因为图像中的每个像素将产生子图像。但我的代码只返回一个值。有什么问题?

enter image description here

1 个答案:

答案 0 :(得分:1)

如果您希望在使用高斯内核过滤图像后计算每个子图像的平均值,只需将图像与mean or average filter进行卷积即可。这将收集原始图像中的子图像,并且对于每个输出位置,您将计算平均值。

首先假设掩模大小为3 x 3,只需将conv2与3 x 3掩码一起使用,该掩码具有全部1/9系数。换句话说:

%// 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子图像的平均值。

您还可以使用带有标记average的{​​{3}}并指定蒙版的大小/宽度来创建平均蒙版。鉴于您已经在代码中使用它,您已经知道它的存在。因此,你也可以这样做:

mask = fspecial('average', 3);

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

除了

conv2专为一般二维信号而设计。如果您要过滤图片,我建议您改用fspecial。您应该有权访问它,因为fspecial是图像处理工具箱的一部分,imfilter也是如此。已知imfilterconv2更有效,并且如果可用,也会使用imfilter(基本上如果您在具有支持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中看到的子图像。您可以使用非常强大的Intel Integrated Performance Primitives (Intel IPP)函数,该函数是图像处理工具箱的一部分。你这样称呼它:

B = im2col(A,[m n]);

A将是您的输入图片,B将是一个大小为mn x L的矩阵,其中L将是可能的子图像总数存在于您的图像中,mn分别是每个子图像的高度和宽度。 im2col的工作原理是,对于图片中存在的每个子图片,它会使它们变形以使其适合B中的单个列。因此,B中的每一列都会生成一个子图像,并将其扭曲为一列。然后,您可以使用B中的每一列进行GMM建模。

但是,im2col仅返回不超出范围的有效子图像。如果要处理边缘和边角情况,则需要先填充图像。使用im2col来促进此填充。因此,为了做你所要求的,我们只需:

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会以列主要格式扭曲这些列。这意味着对于您拥有的每个子图像,它会占用子图像中的每一列并将它们堆叠在一起,从而为您提供9 x 1列。您将拥有L个子图像,并且这些子图像水平连接以生成9 x L矩阵。另外,请记住,子图像是从上到下,然后从左到右读取的,因为这是以列主要顺序运行的MATLAB的本质。