Считать значения (M, N) изображения из (2, MN) матрицы в Python - PullRequest
0 голосов
/ 30 октября 2018

Предположим, что у меня есть (M, N) изображение J (с формой (M, N, 3)). И у меня есть (2, MN) матрица K, как это:

0 0 0 ... 0 1 1 1 ... 1 ............. M M M ... M

0 1 2 ... N 1 2 3 ... N ............. 1 2 3 ... N

Теперь я умножил вышеприведенную матрицу на матрицу 2 на 2, чтобы получить новую матрицу T того же размера, что и K.

Теперь я хочу создать новое изображение, в котором пиксель (r, s) в этом новом изображении равен значению (R, G, B) пикселя старого изображения, которое находится в r * N + М колонна Т.

Я хочу сделать это векторизованным способом, если это возможно. Я не хочу использовать for-циклы (я уже знаю, как сделать это с помощью for-циклов, но это очень медленно). На самом деле меня интересует эта проблема, потому что я хочу применить преобразование гомографии векторизованным способом.

Любая помощь приветствуется. Вот зацикленная версия для ясности того, что я хочу:

for r in range(0,M):
    for s in range(0,N):
        x, y = T[:,r*N+s]
        new_image[r,s] = J[x,y]

1 Ответ

0 голосов
/ 30 октября 2018

Вы можете почти напрямую использовать ваш индексный массив благодаря удачному расположению индексов внутри:

import numpy as np

# set up dummy input
M,N = 300,400
J = np.random.rand(M, N, 3)
T = np.array([np.random.randint(0, M, M*N), np.random.randint(0, N, M*N)])

# original    
new_image = np.empty_like(J)
for r in range(0,M):
    for s in range(0,N):
        x, y = T[:,r*N+s]
        new_image[r,s] = J[x,y]

# vectorized new
new_image_vect = J[tuple(T)].reshape(J.shape)

Проверка:

>>> np.array_equal(new_image, new_image_vect)
True

То, как работает вышеупомянутое, не совсем тривиально, потому что расширенная индексация - переменчивая вещь . То, что я написал выше, эквивалентно

J[(T[0,...], T[1,...])].reshape(J.shape) -> J[T[0,...], T[1,...]].reshape(J.shape)

Теперь первая часть более понятна: возьмите каждый элемент в первой строке T и используйте его в качестве первого индекса J, затем возьмите соответствующий элемент во второй строке T и используйте его как соответствующий второй индекс J. Эта часть вроде обложек J[x,y] в зацикленной версии.

Но тогда, поскольку мы по существу индексируем массив с 1d массивами длины M*N, форма полученного массива также будет иметь форму M*N вдоль его первого измерения (и конечного измерения размера 3). Таким образом, нам нужно reshape результат вернуться к (M,N,3).

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

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