OpenCV python, как питонически применить операцию к одному каналу? - PullRequest
1 голос
/ 30 апреля 2019

Предположим, у меня есть изображение OpenCV с размером 1000x1000x3

Предположим, я хочу применить операцию на пиксель

if pixel == (255, 255, 255): 
     pixel = (0, 255, 0)

Очевидно, я мог бы просто написать 2 для циклов и сделать это таким образом. Однако для петель доступ к пикселям в python очень медленный.

Мне сказали, что есть питонский способ делать такие вещи, например, img = cv2.min(img, 255) найдет минимум значения пикселя мата и 255, эффективно ограничивая диапазон значений на изображении одного канала.

Тем не менее, я не уверен, как применять на пиксель, если условно, к каждому пикселю аналогичным образом.

Ответы [ 2 ]

3 голосов
/ 30 апреля 2019

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

Например, заменить четные числа в матрице 5x5 на 42:

import numpy as np

a = np.arange(5*5).reshape((5,5))
print(a)

Out:

array([[ 0,  1,  2,  3,  4],
   [ 5,  6,  7,  8,  9],
   [10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19],
   [20, 21, 22, 23, 24]])

a[a%2==0] = 42
print(a)

Это дает:

array([[42,  1, 42,  3, 42],
   [ 5, 42,  7, 42,  9],
   [42, 11, 42, 13, 42],
   [15, 42, 17, 42, 19],
   [42, 21, 42, 23, 42]])

Для вашего изображения вам нужно немного больше манипуляций.это будет что-то вроде:

myImg = np.arange(1000*1000*3).reshape((1000,1000,3)) # replace with your image
colorVecs = np.reshape(myImg,(-1,3)) #so that each array element is a 1x3 vector
colorVecs[colorVecs == [255,255,255]] = [0,255,0]  #perform your operation

filteredImg = np.reshape(colorVecs,(1000,1000,3)) #back to a normal image

Больше информации о булевых масках здесь

1 голос
/ 30 апреля 2019

Поскольку OpenCV использует массивы Numpy для отображения изображений, мы можем Numpy Slicing / Indexing для доступа к отдельным пикселям или каналам. Например, чтобы применить операцию к вертикальному / горизонтальному каналу, мы можем сделать это

Чтобы изменить вертикальный канал на 50 на черный

blank = np.full((200, 200), 255, dtype=np.uint8)
vertical = blank.copy()
vertical[:,50] = 0

Чтобы изменить горизонтальный канал на 50 на черный

horizontal = blank.copy()
horizontal[50,:] = 0

image image image

Полный код

import cv2
import numpy as np

blank = np.full((200, 200), 255, dtype=np.uint8)
cv2.imshow('blank', blank)

vertical = blank.copy()
vertical[:,50] = 0
cv2.imshow('vertical', vertical)

horizontal = blank.copy()
horizontal[50,:] = 0
cv2.imshow('horizontal', horizontal)

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