Векторизовать код для создания трехмерного массива, состоящего из координатных окон из координатного вектора

У меня есть координатный вектор comp_points удерживая пару координат изображения в каждой строке. Теперь я хочу создать массив comp_windows держа nxm-окна изображения вокруг координат comp_points, Эти окна должны быть выровнены по 3-му измерению 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-период с использованием конкатенации или индексации выражения или чего-то еще, но я не могу понять это.

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])))
Другие вопросы по тегам