NumPy/OpenCV 2: как перечислить все пиксели из региона?
Это продолжение моего старого вопроса.
Учитывая непрямоугольную область, как мне перечислить все пиксели из нее и расположить их как один вектор? Порядок не имеет значения (хотя должен быть детерминированным). Есть ли какой-нибудь быстрый способ (или, по крайней мере, стандартная функция), или мой лучший подход - перебирать пиксели на изображении и выбирать только те из ROI?
Дополнительный плюс, если возможно восстановить данные региона из этого вектора позже.
2 ответа
Извлечение региона
Ты можешь использовать numpy.nonzero()
mask_1c = mask[:, :, 0]
indexes = mask_1c.nonzero()
mask_1c
есть, потому что в вашем предыдущем вопросе у вас есть изображение маски 3 канала.
Хранение как вектор
Если вы предпочитаете хранить контент в виде одного массива (вместо набора массивов)
indexes_v = np.array(indexes).T # Returns an Nx2 matrix
Использование региона
Допустим, вы хотели инвертировать этот регион, например:
image[indexes[0], indexes[1], :] = 255 - image[indexes[0], indexes[1], :]
где я предположил, что изображение имеет тип np.uint8
(имеет максимум 255
).
Ты можешь использовать numpy.where()
Функция для этого. Вам не нужно делать итерацию по пикселям.
Я продолжу с вашего последнего вопроса. В принятом ответе маска создана, и вы нарисовали на ней многоугольник, чтобы определить область маски. Что вам нужно сделать, это просто найти, где пиксель 255 в этом изображении маски.
ROI_pixel_locations = np.transpose(np.where(mask[:,:,0]==255))
Это даст вам массив Mx2 из x,y местоположений.
Если вы используете OpenCV 2.4.4 или выше, он имеет функцию cv2.nonzero()
с точно такой же целью.
НОТА:
В предыдущем вопросе принятый ответ создает 3-х канальное изображение маски. Если это было одноканальное изображение маски, вам нужно дать только так:
ROI_pixel_locations = np.transpose(np.where(mask==255))
Но во время операции AND вы изменяете строку следующим образом:
masked_image = cv2.bitwise_and(image,image, mask=mask)