использование numpy.any для сопоставления цвета в opencv дает странные результаты

#python #opencv #numpy

#python #opencv #numpy

Вопрос:

Я пытаюсь включать и выключать ретранслятор на основе определения цвета в кадре с веб-камеры. Поскольку это нужно делать в режиме реального времени, я решил использовать numpy slicing. Проблема в том, что numpy ВСЕГДА определяет цвет, который я ввожу, если я полностью не закрываю камеру, и я просто не понимаю, почему.

Вот соответствующий фрагмент кода:

 import numpy as np
import cv2
import video

while True:
            ret,frame = cam.read()          
            img = frame.copy()
            sens = 20
            b = 0
            #roughly neon green
            img1B = 20
            img1G = 230
            img1R = 50  
            if np.any(np.logical_and(img[:,:,0]>=img1B-sens, img[:,:,0]<=img1B sens)):
                b = True
            else:
                b = False
            if np.any(np.logical_and(img[:,:,1]>=img1G-sens, img[:,:,1]<=img1G sens)):
                g = True
            else:
                g = False
            if np.any(np.logical_and(img[:,:,2]>=img1R-sens, img[:,:,2]<=img1R sens)):
                r = True
            else:
                r = False                       
            print b,g,r  
  

B, G, R не всегда должны быть истинными, если камера не видит неоново-зеленый пиксель, поэтому я не уверен, что происходит.

Ответ №1:

Вам не нужно чрезмерно усложнять проблему, используя numpy операции трижды. Вы можете просто использовать cv2.inRange() и cv2.countNonZero() для выполнения своей работы. Вышеуказанные шаги могут быть модулированы методом, который вы можете вызвать из своего while цикла для обработки каждого кадра веб-камеры.

 import cv2

def detect_color_blob(img_BGR, blob_color_BGR, tolerance, threshold):
    blob_color_lower = [blob_color_BGR[0] - tolerance, blob_color_BGR[1] - tolerance, blob_color_BGR[2] - tolerance]
    blob_color_upper = [blob_color_BGR[0]   tolerance, blob_color_BGR[1]   tolerance, blob_color_BGR[2]   tolerance]

    # Get a Binary Mask, where 255 => blob color found and 0=> blob color NOT found
    mask = cv2.inRange(img_BGR, blob_color_lower, blob_color_upper)

    # Check if the detected number of pixels is greater than threshold.
    return cv2.countNonZero(mask) > threshold