MATLAB:在不使用循环的情况下提取矩阵的多个部分

时间:2009-05-25 09:42:11

标签: matlab matrix extract

我有一个巨大的2D矩阵,我想从中提取15个不同的100x100部分。我有两个向量x和y,其中保存了零件的左上角索引。我用过这样的东西:

result = cam1(x(1:end):(x(1:end)+99), y(1:end):(y(1:end)+99));

但结果只是100x100矩阵而不是15x100x100。为什么?

我知道可以使用循环轻松完成,但我们不允许使用循环(它是图像处理练习的一部分)。另一种可能性是写出所有15条线,但这有点难看。

你有什么优雅的解决方案吗?感谢。

3 个答案:

答案 0 :(得分:6)

有许多方法可以在没有循环的情况下完成此操作。大多数解决方案涉及将矢量 x y 扩展为更大的索引矩阵,并且可能会使用一个或多个函数REPMATBSXFUN,或SUB2IND。可以找到一个很好的矩阵索引教程here

但是,既然你要求一个优雅的解决方案,那么这里有点不寻常。它使用anonymous functions以及函数ARRAYFUNCAT

indexFcn = @(r,c) cam1(r:(r+99),c:(c+99));
result = arrayfun(indexFcn,x,y,'UniformOutput',false);
result = cat(3,result{:});

<强>说明

第一行创建匿名函数。这是一个简单的单行函数,可以即时创建,而无需将其放在m文件中。该函数定义了两个输入 r c ,用于从 cam1 中提取100 x 100的子矩阵。变量 indexFcn 存储function handle,用于调用该函数。请注意,匿名函数使用的 cam1 值为 static 。即使变量 cam1 中的值发生变化,匿名函数仍会在创建函数时使用 cam1 中的值。

第二行调用ARRAYFUN,它将函数应用于数组的每个元素。 ARRAYFUN循环遍历 x y 中的每个条目,并将值传递给 indexFcn 。输出存储在结果中,这是一个15个元素的单元格数组,其中每个单元格包含一个100×100的矩阵。

第三行使用CAT函数将100×100矩阵连接成100×100×15的矩阵。

答案 1 :(得分:4)

由于这显然是家庭作业,我不会给你完整的答案。

有几种方法可以索引矩阵。如果设置了分散的索引,则需要使用单个索引。因此,如果

A = rand(5,6)
A =
      0.81472      0.09754      0.15761      0.14189      0.65574      0.75774
      0.90579       0.2785      0.97059      0.42176     0.035712      0.74313
      0.12699      0.54688      0.95717      0.91574      0.84913      0.39223
      0.91338      0.95751      0.48538      0.79221      0.93399      0.65548
      0.63236      0.96489      0.80028      0.95949      0.67874      0.17119

A(3:4,3:4)

将从A产生2x2子矩阵。但我们也可以找到子矩阵为

reshape(A([13 14 18 19]),[2 2])
ans =
      0.95717      0.91574
      0.48538      0.79221

为什么我选择这个索引集?要获得答案,您需要阅读有关sub2ind的信息。

[I,J] = ndgrid(3:4,3:4);
sub2ind([5 6],I(:),J(:))
ans =
    13
    14
    18
    19

最后,看起来你想要从提取的部分获得15x100x100阵列。因此,从我展示的部分构建必要的索引数组。你需要在最后进行最后的重塑,以使其形状合适。

这应该给你足够的开始完成你的作业。

答案 2 :(得分:0)

你认为一切都很困难,试试这个:mat2cell