我怎样才能 运行 在 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()