Каков эквивалентный способ сделать этот тип pythonic векторизованного назначения в MATLAB? - PullRequest
0 голосов
/ 12 декабря 2018

Я пытаюсь перевести эту строку кода из Python в MATLAB:

new_img[M[0, :] - corners[0][0], M[1, :] - corners[1][0], :] = img[T[0, :], T[1, :], :]

Итак, естественно, я написал что-то вроде этого:

new_img(M(1,:)-corners(2,1),M(2,:)-corners(2,2),:) = img(T(1,:),T(2,:),:);

Но это дает мнеследующая ошибка при достижении этой строки:

Запрошенный массив 106275x106275x3 (252,4 ГБ) превышает максимальный размер предпочтительного размера массива.Создание массивов, превышающих этот предел, может занять много времени и привести к тому, что MATLAB перестанет отвечать на запросы.См. Ограничение размера массива или панель настроек для получения дополнительной информации.

Это заставило меня поверить, что это не назначает вещи правильно.Img - самое большее 1000 × 1500 RGB-изображений.Тот же код работает менее чем за 5 секунд в Python.Как я могу сделать векторное присваивание, как код в первой строке в MATLAB?

Кстати, я не вставил все строки своего кода в этот пост, чтобы он не был слишком длинным.Если мне нужно добавить что-нибудь еще, пожалуйста, дайте мне знать.

Редактировать: Вот объяснение того, что я хочу, чтобы мой код делал (в основном, это то, что делает код Python):

Рассмотрим эту строку кода.Это не настоящий код MATLAB, я просто пытаюсь объяснить, что я хочу сделать:

A([2 3 5], [1 3 5]) = B([1 2 3], [2 4 6])

Он интерпретируется так:

A(2,1) = B(1,2)
A(3,1) = B(2,2)
A(5,1) = B(3,2)
A(2,3) = B(1,4)
A(3,3) = B(2,4)
A(5,3) = B(3,4)
...
...
...

Вместо этого я хочу, чтобыинтерпретировать так:

A(2,1) = B(1,2)
A(3,3) = B(2,4)
A(5,5) = B(3,6)

1 Ответ

0 голосов
/ 12 декабря 2018

Когда вы делаете A[vector1, vector2] в Python, вы индексируете набор:

A[vector1[0], vector2[0]]
A[vector1[1], vector2[1]]
A[vector1[2], vector2[2]]
A[vector1[3], vector2[3]]
...

В MATLAB аналогичный A(vector1, vector2) вместо этого индексирует набор:

A(vector1(1), vector2(1))
A(vector1(1), vector2(2))
A(vector1(1), vector2(3))
A(vector1(1), vector2(4))
...
A(vector1(2), vector2(1))
A(vector1(2), vector2(2))
A(vector1(2), vector2(3))
A(vector1(2), vector2(4))
...

То есть вы получаете каждую комбинацию показателей.Вы должны думать о нем как о подмассиве, состоящем из строк и столбцов, указанных в двух векторах.

Чтобы выполнить то же самое, что и в коде Python, вам необходимо использовать линейное индексирование:

index = sub2ind(size(A), vector1, vector2);
A(index)

Таким образом, ваш код MATLAB должен делать:

index1 = sub2ind(size(new_img), M(1,:)-corners(2,1), M(2,:)-corners(2,2));
index2 = sub2ind(size(img), T(1,:), T(2,:));

% these indices are for first 2 dims only, need to index in 3rd dim also:
offset1 = size(new_img,1) * size(new_img,2);
offset2 = size(img,1) * size(img,2);
index1 = index1.' + offset1 * (0:size(new_img,3)-1);
index2 = index2.' + offset2 * (0:size(new_img,3)-1);

new_img(index1) = img(index2);

Что средний блок делает здесь, это добавляет линейные индексы для тех же элементов в 3-м измерении.Если ii является линейным индексом для элемента в первом канале, то ii + offset1 является индексом для того же элемента во втором канале, а ii + 2*offset1 является индексом для того же элемента в третьем канале и т. Д.Итак, здесь мы генерируем индексы для всех этих матричных элементов.Операция + выполняет неявное одноэлементное расширение (то, что они называют «вещанием» в Python).Если у вас более старая версия MATLAB, это не получится, вам нужно заменить A+B на bsxfun(@plus,A,B).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...