矢量化代码以创建由坐标向量的坐标窗口组成的三维数组

时间:2017-07-29 16:01:55

标签: matlab indexing vectorization

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

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循环,我可以做到这一点,但我无法弄明白。

1 个答案:

答案 0 :(得分:3)

您的操作已经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])))