Преобразование скаляров в массивы на основе значений: Обработка изображений 2D в 3D - NumPy / Python - PullRequest
1 голос
/ 07 мая 2020

Учитывая Numpy матрицу формы (height, width), я ищу самый быстрый способ создать другую Numpy матрицу формы (height, width, 4), где 4 представляет RGBA значения. Я хотел бы сделать это на основе ценностей; Итак, для всех значений 0 в первой матрице я хотел бы иметь значение [255, 255, 255, 0] во второй матрице в том же месте.

Я хотел бы сделать это с NumPy без необходимости медленно повторяйте, как показано ниже:

for i in range(0, height):
    for j in range(0, width):
        if image[i][j] = 0:
            new_image[i][j] = [255, 255, 255, 0]
        elif image[i][j] = 1:
            new_image[i][j] = [0, 255, 0, 0.5]

Как видите, я создаю матрицу, в которой значение 0 становится прозрачно-белым, а 1 становится зеленым с альфа 0,5; есть ли более быстрые NumPy решения?

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

Ответы [ 2 ]

3 голосов
/ 07 мая 2020

Для более чистого решения, особенно при работе с несколькими метками , мы могли бы использовать np.searchsorted для отслеживания значений для сопоставления, например:

# Edit to include more labels and values here            
label_ar = np.array([0,1]) # sorted label array
val_ar = np.array([[255, 255, 255, 0],[0, 255, 0, 0.5]])

# Get output array
out = val_ar[np.searchsorted(label_ar, image)]

Обратите внимание, что это предполагает, что все уникальные метки из image находятся в label_ar.

Итак, теперь предположим, что у нас есть еще две метки 2 и 3 в image, что-то вроде этого -

for i in range(0, height):
    for j in range(0, width):
        if image[i,j] == 0:
            new_image[i,j] = [255, 255, 255, 0]
        elif image[i,j] == 1:
            new_image[i,j] = [0, 255, 0, 0.5]
        elif image[i,j] == 2:
            new_image[i,j] = [0, 255, 255, 0.5]
        elif image[i,j] == 3:
            new_image[i,j] = [255, 255, 255, 0.5]

Мы соответствующим образом отредактируем метки и значения и будем использовать то же решение searchsorted -

label_ar = np.array([0,1,2,3]) # sorted label array
val_ar = np.array([
    [255, 255, 255, 0],
    [0, 255, 0, 0.5],
    [0, 255, 255, 0.5],
    [255, 255, 255, 0.5]])
0 голосов
/ 07 мая 2020

Вы правы np.where вот как вы решаете эту проблему. Где векторизованная функция, поэтому она должна быть намного быстрее, чем ваше решение.

Я делаю здесь предположение, что он не имеет elif, о котором я знаю, но вы можете обойти это, вложив инструкции where.

 new_image = np.where(
           image == 0,
           [255, 255, 255, 0],
           np.where(
                image == 1,
                [0, 255, 0, 0.5],
                np.nan
           )
      )
...