Numpy: эффективное отображение отдельных значений в массивах np - PullRequest
0 голосов
/ 05 апреля 2020

У меня есть массив 3D numpy, представляющий изображение в цветовом пространстве HSV (форма = (h = 1000, w = 3000, 3)).

Последнее измерение изображения - [H, S, V]. Я хочу вычесть 20 из канала H из всех пикселей, если значение пикселя> 20, но оставить S и V без изменений. Я написал следующую векторизованную функцию:

def sub20(x):
# x is a array in the format [H,S, V]
       return np.uint8([H-20, S, V])
 vec= np.vectorize(sub20, otypes=[np.uint8],signature="(i)->(i)")
 img2= vec(img1)

Что делает эта векторизованная функция, так это принимает последнее измерение изображения [H, S, V] и выводит [H-20, S, V]. знать, как заставить его вычитать 20, если H больше 20. Это также занимает 1 минуту. Я хочу, чтобы скрипт принимал веб-канал в режиме реального времени. Есть ли способ сделать это быстрее?

Спасибо

Ответы [ 2 ]

0 голосов
/ 05 апреля 2020

Вы можете просто нарезать с условием:

img1[:,:,0][img1[:,:,0]>=20] -= 20

Или также использовать np.where:

img1[:,:,0] = np.where(img1[:,:,0]>=20, img1[:,:,0]-20, img1[:,:,0])
0 голосов
/ 05 апреля 2020

Вам нужно использовать функцию векторизации?

В противном случае вы можете использовать только следующую команду:

# if you want to make change directly on same image.
img1[:,:,0] -= 20

# if you want to leave img1 in the same state.
img2 = np.array(img1)
img2[:,:,0] = img1[:,:,0] - 20

Обновить (12:08 - 5.4.2020) Чтобы учесть, что значения никогда не опускаются ниже 0, я бы рекомендовал рассчитать его в два этапа, как упоминал Меркурий:

# if you want to make changes directly on same image.
img1[:,:,0] -= 20
img1[img1[:,:,0] < 0] = 0

# if you want to leave img1 in the same state.
img2 = np.array(img1)
img2[:,:,0] = img2[:,:,0] - 20
img2[img2[:,:,0] < 0] = 0
...