OpenCV record video and draw position of LED

Viewed 72

I'm making an app that records a users face during the course of having different LEDs shine on it. The user stands in front of the device and 4 LEDs in the corners take turns turning on and off. I'm doing this with the adafruit neopixel library. This is working fine. My next goal is to have the recorded image draw a little circle in the frame corresponding to which LED is turned on at the moment. So if the top right LED is on, I want there to be a little circle drawn in the top right of the frame indicating which LED is active. I can also draw on the frames just fine when viewing regular webcam footage.

However, my issue is combining the two. If I run a loop to process the frames, then I can't accurately control the timing of the LEDs. If I put a delay or sleep function to time the LEDs the way they need to, then the loop processing the frames also stops. if I put the loop at the top of the script, it never calls the functions to blink the LEDs because it never breaks from while True and if I put it at the bottom, the LEDs blink through their functions before the video capture starts.

So for regular webcam video:

cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Display the resulting frame
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

And to blink one LED 3 times:

def blinkTopRight():
    pixels[3] = (255,0,0)
    sleep(1)
    pixels[3] = (0,0,0)
    sleep(1)
    pixels[3] = (255,0,0)
    sleep(1)
    pixels[3] = (0,0,0)
    sleep(1)
    pixels[3] = (255,0,0)
    sleep(1)
    pixels[3] = (0,0,0)
    sleep(1)

My goal is to have something like this when the LED is on:

pixels[3] = (255,0,0)
frame = cv2.circle(frame, (100,100), 10, (0, 255, 0), 3)
cv2.imshow("Vid", frame)

and then when it's off, no drawing:

pixels[3] = (0,0,0)
cv2.imshow("Vid", frame)

but obviously that's not working and I can't figure out how to combine the timed blinks with an infinite while True loop for video recording. Any help is appreciated.

1 Answers

Check the time in each iteration if it is a moment for switching:

import time

p_time = time.time()
on = False
while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()
    c_time = time.time()
    
    if on:
        frame = cv2.circle(frame, (100, 100), 10, (0, 255, 0), 3)
       
        
    if c_time - p_time > 1:

        on = not on
        if on:
            pixels[3] = (255,0,0)
        else:
            pixels[3] = (0,0,0)
        p_time = c_time

    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
Related