python opencv在网络摄像头视频中使用putText显示时间倒计时

时间:2015-02-09 23:37:00

标签: python opencv time

目标:

我想在网络摄像头获得的每一帧上放置文字,以便文本" 3"," 2"," 1"可以显示一秒钟。从而描绘倒数计时器。在倒计时之后,应该将一个帧写入文件,即保存到磁盘。只要视频流尚未关闭,这应该是可重复的。

每个帧都是在一个while循环中获得的,并且由于硬件配置,摄像机可能具有未知的帧速率或者更糟糕的是,摄像机每秒检索的帧数在运行摄像机的过程中可能会有所不同。

time.sleep()无法使用,因为它会冻结while循环并中断窗口中显示的视频流。

另一个while while循环中的循环是不可接受的,因为它大大减慢了处理器的速度,每秒处理的帧数减少,使得视频流非常不连贯。

我尝试过的事情:

import cv2
import sys
import time

# Initialize variables
camSource = -1
running = True
saveCount = 0
nSecond = 1
totalSec = 3.0
keyPressTime = 0.0
startTime = 0.0
timeElapsed = 0.0
startCounter = False
endCounter = False

# Start the camera
camObj = cv2.VideoCapture(camSource)
if not camObj.isOpened():
    sys.exit('Camera did not provide frame.')

frameWidth = int(camObj.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
frameHeight = int(camObj.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))

# Start video stream
while running:
    readOK, frame = camObj.read()

    # Display counter on screen before saving a frame
    if startCounter:
        if nSecond <= totalSec: 
            # draw the Nth second on each frame 
            # till one second passes  
            cv2.putText(img = frame, 
                        text = str(nSecond),
                        org = (int(frameWidth/2 - 20),int(frameHeight/2)), 
                        fontFace = cv2.FONT_HERSHEY_DUPLEX, 
                        fontScale = 3, 
                        color = (255,0,0),
                        thickness = 2, 
                        lineType = cv2.CV_AA)

            timeElapsed += (time.time() - startTime)
            print 'timeElapsed:{}'.format(timeElapsed)

            if timeElapsed >= 1:
                nSecond += 1
                print 'nthSec:{}'.format(nSecond)
                timeElapsed = 0
                startTime = time.time()

        else:
            # Save the frame
            cv2.imwrite('img' + str(saveCount) + '.jpg', frame)  
            print 'saveTime: {}'.format(time.time() - keyPressTime)

            saveCount += 1
            startCounter = False
            nSecond = 1

    # Get user input
    keyPressed = cv2.waitKey(3)
    if keyPressed == ord('s'):
        startCounter = True
        startTime = time.time()
        keyPressTime = time.time()
        print 'startTime: {}'.format(startTime)
        print 'keyPressTime: {}'.format(keyPressTime)

    elif keyPressed == ord('q'):
        # Quit the while loop
        running = False
        cv2.destroyAllWindows()

    # Show video stream in a window    
    cv2.imshow('video', frame)

camObj.release()

问题:

我可以看到我的方法几乎可以工作,但time.time()返回的cpu ticks与真实世界秒不同。每个数字的文本都不会显示一整秒,文件保存得太快(在1.5秒内而不是3秒内)。

我接受答案:

如果您可以展示如何正确定时以及如何显示&#34; 3&#34;,&#34; 2&#34;,&#34; 1&#34;而不是我当前显示&#34; 1&#34;,&#34; 2&#34;,&#34; 3&#34;

的方法

2 个答案:

答案 0 :(得分:2)

经过两天的努力并阅读datetime模块后,我得到了我需要的东西。但是,如果它更像pythonic,我可以接受除我之外的答案。

import cv2
import sys
from datetime import datetime

# Initialize variables
camSource = -1
running = True
saveCount = 0
nSecond = 0
totalSec = 3
strSec = '321'
keyPressTime = 0.0
startTime = 0.0
timeElapsed = 0.0
startCounter = False
endCounter = False

# Start the camera
camObj = cv2.VideoCapture(camSource)
if not camObj.isOpened():
    sys.exit('Camera did not provide frame.')

frameWidth = int(camObj.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH))
frameHeight = int(camObj.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT))

# Start video stream
while running:
    readOK, frame = camObj.read()

    # Display counter on screen before saving a frame
    if startCounter:
        if nSecond < totalSec: 
            # draw the Nth second on each frame 
            # till one second passes  
            cv2.putText(img = frame, 
                        text = strSec[nSecond],
                        org = (int(frameWidth/2 - 20),int(frameHeight/2)), 
                        fontFace = cv2.FONT_HERSHEY_DUPLEX, 
                        fontScale = 6, 
                        color = (255,255,255),
                        thickness = 5, 
                        lineType = cv2.CV_AA)

            timeElapsed = (datetime.now() - startTime).total_seconds()
#            print 'timeElapsed: {}'.format(timeElapsed)

            if timeElapsed >= 1:
                nSecond += 1
#                print 'nthSec:{}'.format(nSecond)
                timeElapsed = 0
                startTime = datetime.now()

        else:
            cv2.imwrite('img' + str(saveCount) + '.jpg', frame)  
#            print 'saveTime: {}'.format(datetime.now() - keyPressTime)

            saveCount += 1
            startCounter = False
            nSecond = 1

    # Get user input
    keyPressed = cv2.waitKey(3)
    if keyPressed == ord('s'):
        startCounter = True
        startTime = datetime.now()
        keyPressTime = datetime.now()
#        print 'startTime: {}'.format(startTime)
#        print 'keyPressTime: {}'.format(keyPressTime)

    elif keyPressed == ord('q'):
        # Quit the while loop
        running = False
        cv2.destroyAllWindows()

    # Show video stream in a window    
    cv2.imshow('video', frame)

camObj.release()

答案 1 :(得分:0)

这是我自己实现的一个版本的无数的倒数计时器显示,在10秒视频输出之前为5秒!请在评论中告诉我任何问题!

    def draw_text(frame, text, x, y, color=(255,0,255), thickness=4, size=3):
            if x is not None and y is not None:
                cv2.putText(
                    frame, text, (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, size, color, thickness)

    import numpy as np
    import cv2
    import time
    #timeout = time.time() + 11   # 10 seconds from now
    cap = cv2.VideoCapture(0)
    init_time = time.time()
    test_timeout = init_time+6
    final_timeout = init_time+17
    counter_timeout_text = init_time+1
    counter_timeout = init_time+1
    counter = 5
    while(cap.isOpened()):
        ret, frame = cap.read()
        if ret==True:
            center_x = int(frame.shape[0]/2)
            center_y = int(frame.shape[0]/2)
            if (time.time() > counter_timeout_text and time.time() < test_timeout):
                draw_text(frame, str(counter), center_x, center_y)
                counter_timeout_text+=0.03333
            if (time.time() > counter_timeout and time.time() < test_timeout):
                counter-=1
                counter_timeout+=1
            cv2.imshow('frame', frame)
            if (cv2.waitKey(1) & 0xFF == ord('q')) or (time.time() > final_timeout):
                break
        else:
            break
    # Release everything if job is finished
    cap.release()
    cv2.destroyAllWindows()