I'm working in a project with OCR using a webcam. I would like to know how can I run a function every 3 seconds (for example) while the principal code still running. The code is very long. So I use the following to exemplify:
import cv2
cap = cv2.VideoCapture(0)
def capture():
cv2.imwrite("frame.jpg", frame)
while(1):
ret, frame = cap.read()
cv2.imshow('Webcam', frame)
(_, cnt, _) = cv2.findContours(frame, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
if len(cnt) > 10:
# here I want to call capture() function every 3 seconds
if cv2.waitKey(1) & 0xFF == ord('x'):
break
cap.release()
cv2.destroyAllWindows()
I used time.sleep(3)
after the statments of capture()
function but it pause the continuous capture of the frame. I don't want it. I need something like a software interruption. When the flag shoots, the code of function run but the while cycle continues working.
I'm using python 2.7 on Windows 7.
I hope you understand my purpose. I rode about daemon and threads but I can't interpret so much.
Probably best to do this with threads ( see multiprocessing ), but easy solution below
Note: Does not fire exactly every 3 seconds as opencv functions take time and probably wait for your webcam to give frames.
Note 2: If not using any kind of multi threading your OCR code WILL block your webcam captures, so make your OCR fast or look into above link.
from time import time
t = time() # starting time
while(1):
# do stuff
t_current = time() # current time
# if more than 3 seconds passed:
if t_current - t > 3:
t = t_current
# do other stuff
Here is a rather simple solution using threads. You mentioned about not able to exit the app using ctrl-C. This is because the thread is a separate task and you will have to hit ctrl-C again to kill that thread. To fix it, I've catched KeyboardInterrupt
and stopped the task accordingly. Try this out. The code is pretty self-explanatory, but let me know in case you have any doubts.
import threading
import cv2
exitTask = False
def threadTask():
global frame
if not exitTask:
threading.Timer(1.0, threadTask).start()
cv2.imwrite("Threads.jpg", frame)
print "Wrote to file"
cap = cv2.VideoCapture(0)
try:
ret, frame = cap.read()
except Exception as err:
print err
exit(0)
threadTask()
while(True):
try:
ret, frame = cap.read()
cv2.imshow("Cam", frame)
cv2.waitKey(1)
except KeyboardInterrupt:
exitTask = True
cv2.destroyAllWindows()
exit(0)
You can use it like this
import cv2
import threading
import time
cap=cv2.VideoCapture(0)
main_loop_running = True
def capture():
global main_loop_running, frame
while (main_loop_running):
cv2.imwrite("frame.jpg", frame)
time.sleep(3)
ret, frame = cap.read()
cv2.imshow('Webcam', frame)
child_t = threading.Thread(target=capture)
child_t.setDaemon(True)
child_t.start()
while(1):
ret, frame = cap.read()
cv2.imshow('Webcam', frame)
# here I want to call capture() function every 3 seconds
if cv2.waitKey(1) & 0xFF == ord('x'):
break
main_loop_running = False
child_t.join()
cap.release()
cv2.destroyAllWindows()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.