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

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

问题描述:

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

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

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

    %% 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

+0

对于2D矩阵/信号,“平均值(KI)”将给出单个行向量,其中每个元素是位于该KI处索引处的**列**的均值。根据你的描述,这当然不是你想要的。无论哪种方式,我都提供了一个答案。 – rayryeng 2015-02-05 18:59:20

+0

是的,我错误地使用函数意味着(KI) – Jame 2015-02-05 19:04:28

如果这是你来计算各个子图像中的平均值,一旦你与高斯内核过滤你的形象的愿望,只要你的卷积图像与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×3子图像。

您还可以使用fspecial与标记average并指定掩码的大小/宽度来创建平均掩码。鉴于你已经在你的代码中使用它,你已经知道它的存在。同样,你也可以这样做:

mask = fspecial('average', 3); 

上面的代码假定宽度和面罩的高度是一样的,所以它会创造一切1/9系数的3×3面具。

除了

conv2被设计用于一般的2D信号。如果您想要过滤图片,我建议您改用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翘曲列专业格式的这些列。这意味着对于您所拥有的每个子图像而言,它会将子图像中的每一列都叠加在一起,从而为您提供9 x 1列。您将有L全部子图像,并且它们水平连接以产生9 x L矩阵。此外,请记住,子图像从顶部到底部被读取为,然后从左到右被读取为,因为这是以列主要顺序操作的MATLAB的性质。

+0

谢谢rayryeng,它是非常明确的代码。但是,我有一个简短的问题。如果我想从I.中提取这些子图像,该怎么做。因为卑鄙是我的一个简单任务。另一个任务是找到每个子图像使用高斯混合模型的pdf。对于高斯混合器模型完成。现在我想为每个子图像应用该功能。预先感谢 – Jame 2015-02-05 18:59:33

+0

@ user8430 - 使用'im2col'。我会更新我的答案。 – rayryeng 2015-02-05 19:00:07

+0

@ user8430 - 我已经更新了我的答案。祝你好运! – rayryeng 2015-02-05 19:07:06