0

I'm trying to write a code so that a webcam will take a picture every hour for an undetermined amount of time (2 weeks for now). Here's what I have so far (which works) :

t0=time.perf_counter()
time_max=3600*24*14
time_step= 3600

while(True):
    tc=time.perf_counter()
    crit = tc-t0
    if (crit>time_max) : 
        cap.release()
        break
    cap.open(num_cam,api)
    cap.set(cv2.CAP_PROP_FOCUS,70)
    ret=cap.grab() #takes a picture
    tst,frm=cap.retrieve()
        cv2.imwrite('test1h_'+str(np.round(crit,2))+'_f70.png',frm)
        cap.release()
        time.sleep(time_step)
pass

I would like for this loop to stop if I press 'q' for example, and for the webcam to take a picture if I press 'p', how could I implement that ? I read you can you can use cv2.waitKey but I don't know where to put that in the code. I also read that you can use the nodule "keyboard" but that it requires a root in linux and I work on windows.

5
  • Do you absolutely want to do this with cv2, or would something like pyinput be fine as well? Commented Dec 5, 2021 at 20:40
  • waitKey only works if you have at least one opencv window (cv2.namedWindow or cv2.imshow). Otherwise it does nothing. Commented Dec 5, 2021 at 20:46
  • press Ctrl+C to cause a KeyboardInterrupt python exception, which you can catch and handle. if you need code to run while also reading from the keyboard, there are different options. (1) "poll" the keyboard. on windows, that would be msvcrt.kbhit(). for linux, I don't know, but you can search on your own (2) run threads (3) see if select()/poll()/whatever can check for data on stdin (they're made for sockets but file descriptors may be supported too, but not on windows) Commented Dec 5, 2021 at 21:21
  • thanks for your replies. @Marsolgen I don't have to use cv2, anything else that works on windows would be fine. Commented Dec 6, 2021 at 9:58
  • @Christoph Rackwitz thanks I'll look into that! Commented Dec 6, 2021 at 9:58

2 Answers 2

1

You can just use this:

if cv.waitKey(20) % 0xFF == ord("d"):
    break

So for example if you want to display a video while not pressing the "d" key, this should work:

while True:
    isTrue, frame = capture.read()

    cv.imshow("Video", frame)

    if cv.waitKey(20) % 0xFF == ord("d"):
        break

capture.realease()
cv.destroyAllWindows()
Sign up to request clarification or add additional context in comments.

Comments

0

Edit: Had mixed up 'char' and 'key', fixed it now.

If you're okay with not using cv2, I would suggest this using pynput:

from pynput import keyboard

def on_press(key):
    print(key)

listener = keyboard.Listener(on_press=on_press)
listener.start()

In your case, you could implement it like this:

import time
from pynput import keyboard

t0=time.perf_counter()
time_max=3600*24*14
time_step= 3600

def on_press(key):
    if key.char=='p':
        #Take picture
        cap.open(num_cam,api)
        cap.set(cv2.CAP_PROP_FOCUS,70)
        ret=cap.grab()
        tst,frm=cap.retrieve()
            cv2.imwrite('test1h_'+str(np.round(crit,2))+'_f70.png',frm)
            cap.release()

    elif key.char=='q':
        #Interrupt
        exit()

listener = keyboard.Listener(on_press=on_press)
listener.start()

while(True):
    tc=time.perf_counter()
    crit = tc-t0
    if (crit>time_max) :
        cap.release()
        break
    cap.open(num_cam,api)
    cap.set(cv2.CAP_PROP_FOCUS,70)
    ret=cap.grab() #takes a picture
    tst,frm=cap.retrieve()
        cv2.imwrite('test1h_'+str(np.round(crit,2))+'_f70.png',frm)
        cap.release()
        time.sleep(time_step)
pass

1 Comment

this is gonna set up a global keyboard hook that acts even when the terminal doesn't have focus

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.