使用Python在OpenCV中从视频自动捕获图像

3 投票
3 回答
7251 浏览
提问于 2025-04-18 12:06

我正在开发一个代码,想让它像自拍定时器一样工作。这个程序会在窗口中显示视频,并且会持续检测人的脸和眼睛。一旦用户选择了一个特定的时间,程序就会在那个时刻捕捉到画面。我现在可以通过使用时间模块中的sleep函数在一定时间后捕捉画面,但这样做会导致视频画面似乎冻结。有没有什么解决办法,让我可以继续看到视频,并且在延迟后自动捕捉画面呢?

我使用的代码是-

import numpy as np
import cv2
import time
import cv2.cv as cv
cap = cv2.VideoCapture(0)

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

# Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# Display the resulting frame
    cv2.imshow('frame',frame)

#time.sleep(01)
    Capture = cv.CaptureFromCAM(0)
    time.sleep(5)
    ret, frame = cap.read()
    image = cv.QueryFrame(Capture) #here you have an IplImage
    imgarray = np.asarray(image[:,:]) #this is the way I use to convert it to numpy array

    cv2.imshow('capImage', imgarray)
    cv2.waitKey(0)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

有人能给我建议吗?任何帮助都非常感谢。

3 个回答

0

使用线程,并把 cv.imshow() 这个函数单独定义出来,不要和你的其他函数放在一起。

import threading
import cv2
def getFrame():
    global frame
    while True:
        frame = video_capture.read()[1]

def face_analyse():
    while True:
#do some of the opeartion you want  

def realtime():
    while True:
        cv2.imshow('Video', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            video_capture.release()
            cv2.destroyAllWindows()
            break

if __name__ == "__main__":
    video_capture = cv2.VideoCapture(cam)
    frame = video_capture.read()[1]

    gfthread = threading.Thread(target=getFrame, args='')
    gfthread.daemon = True
    gfthread.start()
    rtthread = threading.Thread(target=realtime, args='')
    rtthread.daemon = True
    rtthread.start()
    fathread = threading.Thread(target=face_analyse, args='')
    fathread.daemon = True
    fathread.start()

    while True: #keep main thread running while the other two threads are non-daemon
        pass
0

当延迟结束时,你需要再加一行 'cap.read()' 的代码,因为这行代码才是真正用来捕捉图像的。

1

为了让视频能够持续播放,你需要把显示视频的那部分代码重复一遍,然后放进一个循环里。要确保窗口的句柄不会丢失。你可以把捕捉视频的操作设置成鼠标点击事件,并使用一个计时器,在循环开始前记录一个时间点,然后在循环内部再记录一个时间点。当这两个时间点之间的差值等于你预先设定的秒数时,就捕捉那一帧,然后用break跳出循环。

撰写回答