【问题标题】:Vectorize code to create a 3-dimensional array consisting of coordinate windows from a coordinate vector向量化代码以从坐标向量创建由坐标窗口组成的 3 维数组
【发布时间】:2017-07-29 16:01:55
【问题描述】:

我有一个坐标向量comp_points 在每一行中保存一个图像坐标对。现在我想创建一个数组comp_windows,在comp_points 的坐标周围保存一个图像的nxm-windows。这些窗口应沿comp_windows 的第三维对齐。 我解决了这样的任务:

I2=randi([0 255],[500 500]);
comp_points=randi([10 490],[20 2]);
delta_u_window=5;
delta_v_window=5;
for ii=1:size(comp_points,1)
    comp_windows(:,:,ii)=I2(...
        comp_points(ii,1)-delta_u_window:...
        comp_points(ii,1)+delta_u_window,...
        comp_points(ii,2)-delta_v_window:...
        comp_points(ii,2)+delta_v_window);
end

现在我觉得我可以在没有 for-loop 的情况下使用连接或索引表达式或其他东西来做到这一点,但我想不通。

【问题讨论】:

    标签: matlab indexing vectorization


    【解决方案1】:

    您已经拥有slicing 的操作,无需任何计算。所以,我不确定是否值得对其进行矢量化,但无论如何让我们在bsxfun 的大力帮助下将其推出 -

    % Get range arrays
    r1 = [-delta_u_window : delta_u_window];
    r2 = [-delta_v_window : delta_v_window];
    
    % Get row and column indices for all points in comp_points
    r = bsxfun(@plus,r1(:),comp_points(:,1).');
    c = bsxfun(@plus,r2(:),comp_points(:,2).');
    
    % Next up, the work is to combine those row and column indices in a meshed-way
    
    % Get 3D version of r and c - Keeping their last dim aligned and "spreading
    % out" their first dims against each others. Then, perform elementwise
    % summations to give us a summed up array of indices, indexing into which
    % would give us the desired output.
    r3D = reshape(r,size(r,1),1,[]);
    c3D = reshape((c-1)*size(I2,1),1,size(c,1),[]);
    out = I2(bsxfun(@plus, r3D, c3D));
    

    对于permute爱好者,我们可以将最后三个步骤替换为一个步骤,像这样-

    I2(bsxfun(@plus, permute(r,[1,3,2]), permute((c-1)* size(I2,1),[3,1,2])))
    

    【讨论】:

    • 神圣的地狱。是否值得矢量化?!在 octave 中,您的解决方案在 0.005 秒内运行,而 for 循环需要 0.3 秒。我虽然想到了一个基于arrayfun的解决方案,但它仍然在0.3左右。我向你致敬。这只是美丽而正确的代码。
    • @Ash 哇,我想我在这里低估了矢量化的力量!当然感谢您的基准测试和反馈!
    • 哎呀,忘了说,这个时间对应10^4个点。
    • 非常感谢@Divakar。差不多就是我要找的东西。老实说,我什至对这里的表现都不感兴趣。我只是想在矢量化方面提高自己,这让我很烦恼,我无法在这里做到。
    • @Ash 据我所知,arrayfun 永远不会比通常的 for 循环快。这只是让代码更紧凑、更美观的一种方式。
    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 2016-08-15
    • 2015-10-19
    • 2017-05-06
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多