Search code examples
pythonopencvcolorswebcamcolor-detection

Stop the webcam after it detects a specific color


I have written a code which detects light pink color. Now i want to add a code which would automatically close the webcam after it detects the light pink color. Can you help me with this one? Here's the EDITED code:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)

while(1):
    _, frame = cap.read()

    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    lower_pink = np.array([160,50,50])
    upper_pink = np.array([180,255,255])

    mask = cv2.inRange(hsv, lower_pink, upper_pink)

    # Bitwise-AND mask and original image
    res = cv2.bitwise_and(frame,frame, mask= mask)
    cv2.imshow('frame',frame)
    cv2.imshow('mask',mask)
    cv2.imshow('res',res)
    break

if(cv2.countNonZero(mask) > 0):
    print("FOUND")
    raise SystemExit

cv2.destroyAllWindows()

Solution

  • A loop with an unconditional break (and no possible continue) doesn't make sense because then it is semantically no loop.

    The test has to be within the loop, because you want to apply it to each captured image until you hit the first with enough pink in it. And then break the loop. Don't exit the program here, because then the clean up code after the loop isn't executed anymore. Exiting by raising SystemExit is a bit strange anyway, that's what the sys.exit() function is meant to do.

    import cv2
    import numpy as np
    
    def main():
        lower_pink = np.array([160, 50, 50])
        upper_pink = np.array([180, 255, 255])
        threshold = 100  # TODO Adapt to your needs.
        cap = cv2.VideoCapture(0)
    
        while True:
            _, frame = cap.read()
            hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
            mask = cv2.inRange(hsv, lower_pink, upper_pink)
            masked = cv2.bitwise_and(frame, frame, mask=mask)
            cv2.imshow('frame', frame)
            cv2.imshow('mask', mask)
            cv2.imshow('masked', masked)
            # if cv2.countNonZero(mask) > threshold:
            #     print('FOUND')
            #     break
            print(cv2.countNonZero(mask))
            # 
            # Wait for escape key.
            # 
            if cv2.waitKey(500) == 27:
                break
    
        cv2.destroyAllWindows()
    
    
    if __name__ == '__main__':
        main()
    

    The actual threshold test is commented out and replaced by printing the pixel count of the mask so you can determine which value would suit your needs.