我有一个矩阵和2个参数。第一个参数n是要选择的元素数。第二个是窗口大小m 。
我想从矩阵的每个m × m窗口中选择n个元素。结果,我们将得到一个p × q单元格数组,其中p是matrix_height/m而q是matrix_width/m 。
单元格数组的每个元素包含对应窗口中的n最大数。它不一定需要是一个单元数组,它可以是任何将存储必要数据的东西。
回答:
实现此目的的一种方法是,首先使用函数
IM2COL查找矩阵的所有唯一的m × m子矩阵,然后使用函数
SORT以降序对每一列进行
排序 ,最后提取前n行。如果您的初始矩阵为A而输出矩阵为B ,则其外观将如下所示:
B = sort(im2col(A,[mm],'distinct'),1,'descend'); B = B(1:n,:); %# Get the top n values 注意, B将是一个n × m^2矩阵。如果要将其转换为p × 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 × m子矩阵中值的线性索引。您可以使用
IND2SUB函数将其转换为下标,然后移动行和列索引以说明每个m ×× m块的位置:
[B,index] = sort(im2col(A,[mm],'distinct'),1,'descend'); B = B(1:n,:); %# Get the top n values index = index(1:n,:); %# Get the top n values [r,c] = ind2sub([mm],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 现在,您可以使用
MAT2CELL和
RESHAPE函数将行索引,列索引和值一起收集到单元格数组中:
B = mat2cell([r(:) c(:) B(:)],n.*ones(1,size(B,2))); B = reshape(B,nBlocks(1),nBlocks(2)); 另外,您可以使用函数
NUM2CELL ,
STRUCT和
RESHAPE创建结构数组而不是单元格数组:
B = struct('rowIndices',num2cell(r,1),... 'colIndices',num2cell(c,1),... 'values',num2cell(B,1)); B = reshape(B,nBlocks(1),nBlocks(2));
注意:
如果A的尺寸不是m的偶数倍,函数
IM2COL将用零填充部分块。如果任何零填充出现在块的前n值中,则对应的行索引和列索引之一或两者都将超出范围(即,其值大于矩阵A的该维度的大小)。因此,通过检查行索引和列索引是否在范围内,可以确保在后续分析中不包括任何零填充。
更多&回答...