在Python/OpenCV中创建倒计时器

0 投票
2 回答
5303 浏览
提问于 2025-04-18 03:33

我的程序

我正在用Python和OpenCV创建一个虚拟键盘,这个键盘使用一个被追踪的物体(目前是一个蓝色的笔)。当这个物体进入一个矩形的边界时,就会打印出一个字母(现在我只有一个矩形,当物体进入时会打印出“A”)。这一切都运行得很好,不过你可以想象,当物体进入矩形时,字母会非常快速地被打印多次。

我的问题

我需要一种方法来确保用户能够正确输入所需的按键,并且只打印出预期数量的字符。我打算通过创建一个计时器来实现这一点,只有当物体在矩形内停留了大约3秒后,才算一次“按键”。不过,我在实际创建这个计时器时遇到了麻烦,这可能是个非常简单的事情,但我就是想不出解决方案。

我目前尝试过的

我创建了一个简单的循环,设置一个整数变量为一个很大的值,然后当物体与矩形相交时,这个整数就减一,等到它等于0时就打印字母。代码如下:

n = 600000
while n > 0:
n=n-1
print("A")

这个方法的问题在于,当程序进入循环时,几乎就停滞不前了,这让程序变得非常卡顿,画面看起来也很糟糕。我猜这是因为代码在不断地进行减法运算,所以这不是实现我目标的好方法。

我尝试的另一种方法是使用time.sleep(),设置为3秒,但这会暂停程序,所以当物体进入矩形时,屏幕会冻结,这样也不合适。

我的代码

import cv2
import numpy as np
import time
import os

cap = cv2.VideoCapture(0)
pressed = 0


while(1):

# read the frames
_,frame = cap.read()

# smooth it
frame = cv2.blur(frame,(3,3))

# convert to hsv and find range of colors
hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
thresh = cv2.inRange(hsv,np.array((75, 96, 205)), np.array((144, 233, 255)))
thresh2 = thresh.copy()

# find contours in the threshold image
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

# finding contour with maximum area and store it as best_cnt
max_area = 0
for cnt in contours:
    area = cv2.contourArea(cnt)
    if area > max_area:
        max_area = area
        best_cnt = cnt

# finding centroids of best_cnt and draw a circle there
M = cv2.moments(best_cnt)
cx,cy = int(M['m10']/M['m00']), int(M['m01']/M['m00'])
cv2.circle(frame,(cx,cy),5,255,-1)
if cx < 100 and cy < 100:
    cv2.rectangle(frame,(10,0),(100,100),(255,0,0),3)
    pressed = 1
    if pressed == 1:
        n = 9000000
        while n > 0:
            n=n-1
        print("A")
        pressed = 0


else:
    cv2.rectangle(frame,(10,0),(100,100),(0,255,0),3)
    pressed = 0

# Show it, if key pressed is 'Esc', exit the loop
cv2.imshow('frame',frame)
cv2.imshow('thresh',thresh2)
if cv2.waitKey(33)== 27:
    break



# Clean up everything before leaving
cv2.destroyAllWindows()
cap.release()

任何建议都非常感谢!谢谢。

2 个回答

0

你觉得用时间模块怎么样?

下面是一个伪代码:

import time

time_count = 0                  # init

#processing routine start 
start_time = time.time()
processing
#processing ends
end_time = time.time()  
if(object_in_square):
    time_count + = end_time - start_time
    if(time_count > time_defined_by_you (ie 3 sec or whatever you choose to keep):
        # press confirm
        # take action   
else:
    time_count = 0  
1

这段代码主要是用来在OpenCV中设置一个计时器。

  • 这里我使用了datetime库。计时的时长是5秒,如果你想要不同的时长,可以把duration = 5改成你想要的数字。
  • 我用了两个while循环,外面的循环是用来处理主框架的,里面的循环是用来控制计时的。
  • 计时器的概念很简单,diff = (datetime.now() - start_time).seconds。我们只需要把开始的时间和当前的时间相减,然后用.seconds把毫秒转换成秒。
  • 在第二个while循环中,while( diff <= duration ):,如果diff小于duration,那么它会通过这个函数cv2.putText()在框架上显示剩余的时间。

注意:

  • r键可以重置时间,按q键可以退出

代码从这里开始

import cv2
from datetime import datetime

# the duration (in seconds)
duration = 5
cap = cv2.VideoCapture(0+cv2.CAP_DSHOW)
qu = 0
while True:
    
    ret, frame = cap.read()
    start_time = datetime.now()
    diff = (datetime.now() - start_time).seconds # converting into seconds
    while( diff <= duration ):
        ret, frame = cap.read()
        cv2.putText(frame, str(diff), (70,70), cv2.FONT_HERSHEY_SIMPLEX , 1, (255, 0, 0), 2, cv2.LINE_AA)# adding timer text
        cv2.imshow('frame',frame)
        diff = (datetime.now() - start_time).seconds

        k = cv2.waitKey(10)
        if k & 0xFF == ord("r"): # reset the timer
            break
        if k & 0xFF == ord("q"): # quit all
            qu = 1
            break
        
    if qu == 1:
        break

cap.release()
cv2.destroyAllWindows()

撰写回答