我有一个任务是计算从输入图像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相似的尺寸。因为图像中的每个像素将产生子图像。但我的代码只返回一个值。有什么问题?
答案 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
也是如此。已知imfilter
比conv2
更有效,并且如果可用,也会使用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
将是可能的子图像总数存在于您的图像中,m
,n
分别是每个子图像的高度和宽度。 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的本质。