【问题标题】:MATLAB: Extract multiple parts of a matrix without using loopsMATLAB:在不使用循环的情况下提取矩阵的多个部分
【发布时间】:2010-10-28 17:03:21
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: matlab matrix extract


    【解决方案1】:

    有很多方法可以在没有循环的情况下做到这一点。大多数解决方案涉及将向量 xy 扩展为更大的索引矩阵,并且可能会使用一个或多个函数 REPMATBSXFUNSUB2IND .一个很好的矩阵索引教程可以在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 文件中。该函数定义了两个输入 rc,用于从 cam1 中提取一个 100×100 的子矩阵。 indexFcn 变量存储了一个function handle,用于调用该函数。请注意,匿名函数使用的 cam1 的值是 static。即使变量 cam1 中的值发生变化,匿名函数仍然使用创建函数时 cam1 中的值。

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

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

    【讨论】:

    • 发布问题后,我做了更多研究,发现了 arrayfun 函数,我想出了以下内容: digval1 = arrayfun(@(i) sum(sum(cam1(y(i): (y(i)+99), x(i):(x(i)+99)))) / 10000, 1:15);这已经包括我必须做的下一步:计算零件的平均值。但是非常感谢您的帮助,我现在知道我做了正确的事情,并且我已经使用您的代码来获得更漂亮的线条: digval1 = arrayfun(@(i, j) sum(sum(cam1(j:j+ 99, i:i+99))) / 10000, x, y);
    • 很高兴为您提供帮助!仅供参考:如果您可以访问图像处理工具箱,则有一个名为 MEAN2 (mathworks.com/access/helpdesk/help/toolbox/images/mean2.html) 的函数可以简化您的函数: digval1 = arrayfun(@(i,j) mean2(cam1(j:j+99,i :i+99)),x,y);或者,您可以编写自己的 MEAN2 函数:mean2 = @(A) mean(A(:));
    【解决方案2】:

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

    有几种方法可以索引到矩阵中。当您有这样的分散索引集时,您需要使用单个索引。因此如果

    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 的数组。所以从我展示的部分构建必要的索引数组。您需要在最后进行最终整形以使其成为正确的形状。

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

    【讨论】:

      【解决方案3】:

      你觉得太难了,试试这个:mat2cell

      【讨论】:

      • mat2cell 即使在子矩阵在较大矩阵中间隔不均匀的情况下也能工作?原始问题指出,子矩阵的左上角 (x,y) 索引作为输入参数提供,因此子矩阵很可能不是均匀分布的。即它不仅仅是一个均匀分解较大矩阵的过程。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-12
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 2014-05-01
      • 2018-12-06
      相关资源
      最近更新 更多