Векторизовать код для создания трехмерного массива, состоящего из координатных окон из координатного вектора
У меня есть координатный вектор 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])))