如何计算图像 I 中所有子图像的平均值
How to compute the mean value of all sub-imges in image I
我有一个任务是计算从输入图像 I 中提取的子图像的平均值。让我们解释一下我的任务。我有一个图像 I(即 9x9)和一个 window(即尺寸 3x3)。 window 将从图像的左上角到右下角 运行。因此,它将输入图像提取为许多子图像。我想计算这些子图像的平均值。你能给我一些 matlab 代码来计算它吗?
这是我的解决方案。但是没用。
- 首先,我定义了一个window为高斯
- 其次,高斯函数会运行使用卷积函数从左上角到右下角。 (注意,必须使用Gaussian Kernel)
计算每个子项的平均值window
%% 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相似的大小。因为图像中的每个像素都会构成一个子图像。但是我的代码returns只有一个值。有什么问题?
如果您希望在使用高斯核过滤图像后计算每个子图像的平均值,只需将图像与 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 子图像的平均值。
您还可以通过使用带有标志 average
的 fspecial
并指定掩码的大小/宽度来创建平均掩码。鉴于您已经在您的代码中使用它,您已经知道它的存在。因此,您也可以这样做:
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 的子图像。
请注意 im2col
以 column-major 格式扭曲这些列。这意味着对于您拥有的每个子图像,它会获取子图像中的每一列并将它们堆叠在一起,从而为您提供一个 9 x 1
列。您将拥有 L
总子图像,这些子图像被水平连接以生成 9 x L
矩阵。另外,请记住,子图像是从上到下读取的 ,然后是从左到右,因为这是 MATLAB 按列优先顺序运行的本质。
我有一个任务是计算从输入图像 I 中提取的子图像的平均值。让我们解释一下我的任务。我有一个图像 I(即 9x9)和一个 window(即尺寸 3x3)。 window 将从图像的左上角到右下角 运行。因此,它将输入图像提取为许多子图像。我想计算这些子图像的平均值。你能给我一些 matlab 代码来计算它吗?
这是我的解决方案。但是没用。
- 首先,我定义了一个window为高斯
- 其次,高斯函数会运行使用卷积函数从左上角到右下角。 (注意,必须使用Gaussian Kernel)
计算每个子项的平均值window
%% 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相似的大小。因为图像中的每个像素都会构成一个子图像。但是我的代码returns只有一个值。有什么问题?
如果您希望在使用高斯核过滤图像后计算每个子图像的平均值,只需将图像与 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 子图像的平均值。
您还可以通过使用带有标志 average
的 fspecial
并指定掩码的大小/宽度来创建平均掩码。鉴于您已经在您的代码中使用它,您已经知道它的存在。因此,您也可以这样做:
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 的子图像。
请注意 im2col
以 column-major 格式扭曲这些列。这意味着对于您拥有的每个子图像,它会获取子图像中的每一列并将它们堆叠在一起,从而为您提供一个 9 x 1
列。您将拥有 L
总子图像,这些子图像被水平连接以生成 9 x L
矩阵。另外,请记住,子图像是从上到下读取的 ,然后是从左到右,因为这是 MATLAB 按列优先顺序运行的本质。