8

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

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

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

我知道它可以很容易地使用循环来完成,但我们不允许使用循环(这是图像处理练习的一部分)。另一种可能性是编写所有 15 行,但这有点难看。

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

4

3 回答 3

6

有很多方法可以在没有循环的情况下做到这一点。大多数解决方案涉及将向量xy扩展为更大的索引矩阵,并且可能会使用一个或多个函数REPMATBSXFUNSUB2IND。矩阵索引的一个很好的教程可以在这里找到。

但是,由于您要求一个优雅的解决方案,这里有一个有点不寻常的解决方案。它使用匿名函数以及函数ARRAYFUNCAT

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

解释:

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

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

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

于 2009-05-25T17:57:35.527 回答
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 的数组。所以从我展示的部分构建必要的索引数组。您需要在最后进行最终重塑以使其成为正确的形状。

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

于 2009-05-25T13:30:15.560 回答
0

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

于 2012-06-22T00:06:24.727 回答