我怎样才能 运行 在 python 的 while 循环中的每个特定时间执行一个函数?
How can I run a function every specific time within a while cycle on python?
我正在一个使用网络摄像头的 OCR 项目中工作。我想知道如何在主要代码仍然 运行ning 时每 3 秒(例如)运行 一个函数。代码很长。所以我用下面的例子来说明:
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()
我在 capture()
函数的语句之后使用了 time.sleep(3)
,但它暂停了帧的连续捕获。我不想要它。我需要类似软件中断的东西。当旗帜射出时,函数代码 运行 但 while 循环继续工作。
我在 Windows 7.
上使用 python 2.7
希望您能理解我的目的。我骑着守护进程和线程,但我不能解释这么多。
可能最好使用线程 (see multiprocessing),但下面是简单的解决方案
注意:不会恰好每 3 秒触发一次,因为 opencv 函数需要时间并且可能会等待您的网络摄像头提供帧。
注意 2:如果不使用任何类型的多线程,您的 OCR 代码将阻止您的网络摄像头捕获,因此请加快 OCR 速度或查看以上 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
这是一个使用线程的相当简单的解决方案。您提到无法使用 ctrl-C 退出应用程序。这是因为该线程是一个单独的任务,您必须再次按下 ctrl-C 才能终止该线程。为了修复它,我捕获了 KeyboardInterrupt
并相应地停止了任务。试试这个。代码是不言自明的,但如果您有任何疑问,请告诉我。
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)
你可以这样使用它
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()
我正在一个使用网络摄像头的 OCR 项目中工作。我想知道如何在主要代码仍然 运行ning 时每 3 秒(例如)运行 一个函数。代码很长。所以我用下面的例子来说明:
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()
我在 capture()
函数的语句之后使用了 time.sleep(3)
,但它暂停了帧的连续捕获。我不想要它。我需要类似软件中断的东西。当旗帜射出时,函数代码 运行 但 while 循环继续工作。
我在 Windows 7.
上使用 python 2.7希望您能理解我的目的。我骑着守护进程和线程,但我不能解释这么多。
可能最好使用线程 (see multiprocessing),但下面是简单的解决方案
注意:不会恰好每 3 秒触发一次,因为 opencv 函数需要时间并且可能会等待您的网络摄像头提供帧。
注意 2:如果不使用任何类型的多线程,您的 OCR 代码将阻止您的网络摄像头捕获,因此请加快 OCR 速度或查看以上 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
这是一个使用线程的相当简单的解决方案。您提到无法使用 ctrl-C 退出应用程序。这是因为该线程是一个单独的任务,您必须再次按下 ctrl-C 才能终止该线程。为了修复它,我捕获了 KeyboardInterrupt
并相应地停止了任务。试试这个。代码是不言自明的,但如果您有任何疑问,请告诉我。
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)
你可以这样使用它
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()