У меня есть два входных массива: data_arr измерений (i, j, k) и index_arr измерений (i, j).Записи в index_arr являются целыми числами в диапазоне [0, k-1].Я хотел бы создать выходной массив (output_arr) измерений (i, j), где для каждого элемента output_arr index_arr сообщает мне, какой из элементов выбрать.
Другими словами output_arr [i, j] = data_arr [i, j, index_arr [i, j]]
Очевидно, я мог бы сделать это в ледниковом темпе с двойным циклом for.Я бы предпочел что-то более быстрое, используя умную индексацию.В настоящее время лучшее, что я мог придумать, - это создание двух дополнительных 2D матриц размера (i, j).
Ниже приведен простой MWE, созданный с точки зрения создания мозаичного изображения из изображения RGB с использованием стандартного шаблона Байера.Я хотел бы иметь возможность избавиться от X_ind
и Y_ind
import numpy as np
import time
if __name__ == '__main__':
img_width = 1920
img_height = 1080
img_num_colours = 3
red_arr = np.ones([img_height, img_width], dtype=np.uint16) * 10
green_arr = np.ones([img_height, img_width], dtype=np.uint16) * 20
blue_arr = np.ones([img_height, img_width], dtype=np.uint16) * 30
img_arr = np.dstack((red_arr, green_arr, blue_arr))
bayer_arr = np.ones([img_height, img_width], dtype=np.uint16)
bayer_arr[0::2,0::2] = 0 # Red entries in bater patter
# Green entries are already set by np.ones intialisation
bayer_arr[1::2,1::2] = 2 # blue entries in bayer patter
print("bayer\n",bayer_arr[:8,:12], "\n")
mosaiced_arr = np.zeros([img_height, img_width], dtype=np.uint16)
Y_ind = np.repeat(np.arange(0, img_width).reshape(1, img_width), img_height, 0)
X_ind = np.repeat(np.arange(0, img_height).reshape(img_height, 1), img_width, 1)
start_time = time.time()
demos_arr = img_arr[X_ind, Y_ind, bayer_arr]
end_time = time.time()
print(demos_arr.shape)
print("demos\n",demos_arr[:8,:12], "\n")
print("Mosaic took {:.3f}s".format(end_time - start_time))
Редактировать: Как отметил @ Georgy, этот вопрос похож на этот , который я не сделалне могу найти в моих терминах поиска, так что, возможно, этот пост будет подписывать этот пост.Ответы в другом посте применимы, хотя арифметика сплющенного индекса отличается, так как порядок моих измерений отличается.Ответ выше эквивалентен версии ogrid
в другом вопросе.Фактически ogrid
можно использовать, заменив следующее изменение кода:
# Y_ind = np.repeat(np.arange(0, img_width).reshape(1, img_width), img_height, 0)
# X_ind = np.repeat(np.arange(0, img_height).reshape(img_height, 1), img_width, 1)
X_ind, Y_ind = np.ogrid[0:img_height, 0:img_width]
Вы можете реализовать опцию выбора (ограниченную выбором из 32 опций) следующим образом:
start_time = time.time()
demos_arr = bayer_arr.choose((img_arr[...,0], img_arr[...,1], img_arr[...,2]))
end_time = time.time()
Решение ogrid работает за 12 мс, а решение выбора за 34 мс на моей машине