python opencv 在网络摄像头视频中使用 putText 显示时间倒计时
python opencv display time countdown using putText in webcam video
目标:
我想在网络摄像头获取的每一帧上添加文字,以便文字“3”、“2”、“1”各显示一秒钟。因此描绘了一个倒数计时器。倒计时之后,应将一帧写入文件,即保存到磁盘。只要视频流没有关闭,这应该是可重复的。
每一帧都是在 while 循环中获得的,由于硬件配置的原因,相机的帧率可能未知或更糟,在 运行 过程中,相机每秒检索的帧数可能会有所不同相机。
time.sleep()
无法使用,因为它会冻结 while 循环并中断 window 中显示的视频流。
主 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”的方法
经过两天的努力并阅读了 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()
这是我自己实现的一个 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()
目标:
我想在网络摄像头获取的每一帧上添加文字,以便文字“3”、“2”、“1”各显示一秒钟。因此描绘了一个倒数计时器。倒计时之后,应将一帧写入文件,即保存到磁盘。只要视频流没有关闭,这应该是可重复的。
每一帧都是在 while 循环中获得的,由于硬件配置的原因,相机的帧率可能未知或更糟,在 运行 过程中,相机每秒检索的帧数可能会有所不同相机。
time.sleep()
无法使用,因为它会冻结 while 循环并中断 window 中显示的视频流。
主 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”的方法
经过两天的努力并阅读了 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()
这是我自己实现的一个 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()