我有一个矩阵和2个参数。第一个参数n
是要选择的元素数。第二个是窗口大小m
。
我想从矩阵中的每个n
- by - m
窗口中选择m
个元素。因此,我们将有p
- by - q
单元格数组,p
为matrix_height/m
且q
为matrix_width/m
。
单元格数组的每个元素都包含相应窗口中的n
个最大数字。它不一定需要是一个单元格数组,它可以是存储必要数据的任何东西。
答案 0 :(得分:3)
执行此操作的一种方法是首先使用函数IM2COL查找矩阵的所有唯一m
- by - m
子矩阵,然后使用以下内容按降序对每列进行排序函数SORT,最后提取前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
单元格数组,则可以使用NUM2CELL和RESHAPE函数执行此操作:
nBlocks = ceil(size(A)./m); %# The number of blocks in each dimension
B = reshape(num2cell(B,1),nBlocks(1),nBlocks(2));
修改强>
如果你还想得到每个值相对于输入矩阵A
的索引,那就有点复杂了。您可以通过获取SORT的第二个输出来完成此操作,在这种情况下,该输出将是每个m
- { - 1}}子矩阵内的值的线性索引。您可以使用函数IND2SUB将这些转换为下标,然后将行索引和列索引转换为每个m
- by - m
块的位置:
m
现在,您可以使用函数MAT2CELL和RESHAPE将行索引,列索引和值一起收集到单元格数组中:
[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
或者,您可以使用函数NUM2CELL,STRUCT和RESHAPE创建结构数组而不是单元数组:
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));
的维度不是A
的偶数倍,则函数IM2COL将使用零填充部分块。如果任何此零填充出现在块的顶部m
值中,则相应的行和列索引中的一个或两个将超出范围(即,具有大于该维度的大小的值)矩阵n
)。因此,通过检查行和列索引是否在范围内,您可以确保在后续分析中不包括任何零填充。