如何在不使用MATLAB中的循环的情况下,从矩阵的每个m×m窗口提取n个元素?

如何在不使用MATLAB中的循环的情况下,从矩阵的每个m×m窗口提取n个元素?,matlab,matrix,Matlab,Matrix,我有一个矩阵和两个参数。第一个参数n是要选择的元素数。第二个是窗口大小m 我想从矩阵的每个m-by-m窗口中选择n元素数。因此,我们将有一个p-by-q单元数组,其中p是矩阵高度/m,q是矩阵宽度/m 单元格数组的每个元素都包含相应窗口中的n最大数。它不一定是一个单元格数组,它可以是任何可以存储必要数据的东西。实现这一点的一种方法是首先使用函数查找矩阵中所有唯一的m-by-m子矩阵,然后使用函数按降序对每一列进行排序,最后提取顶部的n行。如果您的初始矩阵是A,而输出矩阵是B,则它将是这样的: B

我有一个矩阵和两个参数。第一个参数
n
是要选择的元素数。第二个是窗口大小
m

我想从矩阵的每个
m
-by-
m
窗口中选择
n
元素数。因此,我们将有一个
p
-by-
q
单元数组,其中
p
矩阵高度/m
q
矩阵宽度/m


单元格数组的每个元素都包含相应窗口中的
n
最大数。它不一定是一个单元格数组,它可以是任何可以存储必要数据的东西。

实现这一点的一种方法是首先使用函数查找矩阵中所有唯一的
m
-by-
m
子矩阵,然后使用函数按降序对每一列进行排序,最后提取顶部的
n
行。如果您的初始矩阵是
A
,而输出矩阵是
B
,则它将是这样的:

B = sort(im2col(A,[m m],'distinct'),1,'descend');
B = B(1:n,:);  %# Get the top n values
请注意,
B
将是一个
n
-by-
m^2
矩阵。如果要将其转换为
p
-by-
q
单元阵列,可以使用以下函数和:

编辑:

如果您还想获得每个值相对于输入矩阵
A
的索引,那就有点复杂了。您可以通过从中获取第二个输出来完成此操作,在本例中,这将是每个
m
-by-
m
子矩阵中值的线性索引。您可以使用该函数将其转换为下标,然后移动行和列索引,以说明每个
m
-by-
m
块的位置:

[B,index] = sort(im2col(A,[m m],'distinct'),1,'descend');
B = B(1:n,:);                  %# Get the top n values
index = index(1:n,:);          %# Get the top n values
[r,c] = ind2sub([m m],index);  %# Convert linear indices to subscripts
nBlocks = size(A)./m;          %# The number of blocks in each dimension
r = r+repmat(0:m:(nBlocks(1)-1)*m,n,nBlocks(2));      %# Shift the row indices
c = c+kron(0:m:(nBlocks(2)-1)*m,ones(n,nBlocks(1)));  %# Shift the column indices
现在,您可以使用函数和将行索引、列索引和值收集到一个单元格数组中:

或者,您可以使用函数创建结构数组而不是单元数组,并且:

注意:


如果
a
的维度不是
m
的偶数倍,则该函数将用零填充部分块。如果块的顶部
n
值中出现任何此零填充,则相应的行和列索引中的一个或两个将超出范围(即,矩阵
a
的值大于该维度的大小)。因此,通过检查行和列索引是否在范围内,您可以确保在后续分析中不包含任何零填充。

非常感谢您的帮助。。。这很酷。。。但它实际上会给出每个窗口的矩阵元素。。。我想要的是,它也应该给出这些值w.r.到原始矩阵的位置。每个窗口都应该用包含矩阵元素本身以及元素所在位置的坐标的索引p和q来识别。。。你的评论是正确的。。。它可以改成这样的p-by-q数组。。。唯一缺少的是这些值实际位于矩阵A中的行数和列数。例如,描述第一个窗口的数组(1,1)应导致[col_num row_mum value]。。。我希望现在已经清楚了。Shan@Shan:获取相对于原始矩阵的行和列索引要复杂得多。这需要更多的时间才能弄清楚。@gnovice我希望你有时间的时候可以尝试一下。@Shan:我还添加了一个注意事项,你应该特别注意。你可以看看| blockproc|
[B,index] = sort(im2col(A,[m m],'distinct'),1,'descend');
B = B(1:n,:);                  %# Get the top n values
index = index(1:n,:);          %# Get the top n values
[r,c] = ind2sub([m m],index);  %# Convert linear indices to subscripts
nBlocks = size(A)./m;          %# The number of blocks in each dimension
r = r+repmat(0:m:(nBlocks(1)-1)*m,n,nBlocks(2));      %# Shift the row indices
c = c+kron(0:m:(nBlocks(2)-1)*m,ones(n,nBlocks(1)));  %# Shift the column indices
B = mat2cell([r(:) c(:) B(:)],n.*ones(1,size(B,2)));
B = reshape(B,nBlocks(1),nBlocks(2));
B = struct('rowIndices',num2cell(r,1),...
           'colIndices',num2cell(c,1),...
           'values',num2cell(B,1));
B = reshape(B,nBlocks(1),nBlocks(2));