我想在特定时间间隔使用 opencv 从网络摄像头捕获图像

I want capture images from webcam using opencv at certain intervals

我试过使用时间表。它工作正常,但网络摄像头的取景器停留在初始状态,因此多次只生成一张图像。

有什么帮助吗?

import cv2
import time
import schedule

cam = cv2.VideoCapture(0)

cv2.namedWindow("Webcam")

img_counter = 0


def capture():

    global img_counter

    img_name = "opencv_frame_{}.png".format(img_counter)

    cv2.imwrite(img_name, frame)

    print("screenshot taken")

    img_counter += 1



while True:
    ret, frame = cam.read()

    if not ret:
        print("failed to grab frame")
        break

    cv2.imshow("test", frame)

    k = cv2.waitKey(1)

    if k % 256 == 27:
        print("closing the app")
        break

    else:
        schedule.every(5).seconds.do(capture)
        while 1:
            schedule.run_pending()
            time.sleep(1)

cam.release()

cam.destroyAllWindows()

您遇到缓冲问题。 OpenCV VideoCapture() 将几帧读入缓冲区 - 我认为它是 5,但有一段时间没有检查过,它可能因平台或版本而异。

根据您的情况,有一些可能的解决方法:

  • 当你想要一个帧时调用 read() 4-5 次 - 它只需要几百毫秒
  • 在另一个线程中重复调用 grab() 或在您需要帧之前调用
  • 减小缓冲区的大小,使其只能容纳一个帧。

抱歉我的回答有些模糊,因为我目前还没有准备好进行更多测试。

我认为您的代码可以简化为这样的代码,同时仍然保留定期保存的图像的近实时预览。

import cv2
import schedule

cam = cv2.VideoCapture(0)
cv2.namedWindow("Webcam")
img_counter = 0


def capture():
    global img_counter
    img_name = "opencv_frame_{}.png".format(img_counter)
    cv2.imwrite(img_name, frame)
    print("screenshot taken")
    img_counter += 1


# Set up schedule before loop

schedule.every(5).seconds.do(capture)


while True:
    ret, frame = cam.read()

    if not ret:
        print("failed to grab frame")
        break

    cv2.imshow("test", frame)
    schedule.run_pending()

    k = cv2.waitKey(100)  # 1/10 sec delay; no need for separate sleep

    if k % 256 == 27:
        print("closing the app")
        break

cam.release()
cam.destroyAllWindows()