【问题标题】:python opencv display time countdown using putText in webcam videopython opencv在网络摄像头视频中使用putText显示时间倒计时
【发布时间】:2015-02-09 23:37:00
【问题描述】:

目标:

我想在网络摄像头获得的每一帧上放置文本,以便文本“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 滴答声与现实世界的秒数不同。每个数字的文本一秒钟都没有显示,并且文件保存得太快(在 1.5 秒内而不是 3 秒内)。

我会接受:

如果您可以展示如何正确计时以及如何显示“3”、“2”、“1”而不是我当前显示“1”、“2”、“3”的方法

【问题讨论】:

    标签: python opencv time


    【解决方案1】:

    在挣扎了两天并阅读了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()
    

    【讨论】:

      【解决方案2】:

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

          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()
      

      【讨论】:

      • 你是怎么想到counter_timeout_text+=0.03333的?
      • 目标是在每一帧上绘制。 1/(FPS)30
      • 在持续一秒的帧集上绘图是一项挑战。 FPS 不是恒定的,并且对于不同的相机也不相同。
      • 捕捉时可以设置帧率
      猜你喜欢
      • 1970-01-01
      • 2011-02-05
      • 2017-09-12
      • 2018-03-04
      • 2020-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多