简体   繁体   English

在 python/opencv 中创建倒数计时器

[英]Creating a count down timer in python/opencv

My Program我的程序

Using open CV with python I am creating a virtual keyboard which uses a tracked object (which at the moment is a blue pen) and when said tracked object goes within the boundary of a rectangle a letter is printed (at this time I only have one rectangle which prints out "A" when the object intersects).使用带有 python 的 open CV 我正在创建一个虚拟键盘,它使用一个被跟踪的对象(目前是一支蓝色笔),当所述被跟踪的对象进入矩形的边界内时,会打印一个字母(此时我只有一个当对象相交时打印出“A”的矩形)。 This is all working fine however as you can imagine when the object goes within the boundary of the rectangle the letter is printed out multiple times very quickly.这一切正常,但是正如您可以想象的那样,当对象进入矩形边界时,该字母会很快被打印多次。

My Problem我的问题

I need a way to ensure the user can enter the correct key correctly and the intended amount of said keys character is printed out.我需要一种方法来确保用户可以正确输入正确的密钥并打印出预期数量的所述密钥字符。 The way I intend to do this is by creating a timer that will only register the "key press" once the object has been inside the rectangle for say 3 seconds.我打算这样做的方法是创建一个计时器,该计时器仅在对象位于矩形内 3 秒后才注册“按键”。 I am having trouble however with actually creating the timer, it is probably something incredibly easy however I am having trouble actually coming up with a solution.我在实际创建计时器时遇到了麻烦,这可能是一件非常简单的事情,但是实际上我在想出解决方案时遇到了麻烦。

What I have tried so far到目前为止我尝试过的

I have created a simple for loop which set a integer variable to a high value then once the object intersects with the rectangle the integer is reduced by one then once it equals 0 the letter is printed.我创建了一个简单的 for 循环,它将一个整数变量设置为一个高值,然后一旦对象与矩形相交,整数就减一,然后当它等于 0 时打印字母。 code is as follows:代码如下:

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

The problem with this is that the program pretty much comes to a standstill when it gets into the loop, this make the program incredibly jumpy and the visuals look horrible.这样做的问题是程序在进入循环时几乎停止了,这使得程序非常跳跃并且视觉效果看起来很糟糕。 I assume this is caused by the constant subtractions the code is performing thus this is not a good method for accomplishing my goal.我认为这是由代码执行的不断减法引起的,因此这不是实现我的目标的好方法。

The other method I have tried is using time.sleep() and set it to say 3 seconds however as this pauses the program it again is unsuitable as visually the screen is frozen when the object enters the rectangle.我尝试过的另一种方法是使用 time.sleep() 并将其设置为 3 秒,但是由于这会暂停程序,因此它再次不合适,因为当对象进入矩形时屏幕在视觉上被冻结。

My Code我的代码

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

Any suggestions would be much appreciated Thanks.任何建议将不胜感激谢谢。

How about using time module ?使用时间模块怎么样?

Here is a pseudo code:这是一个伪代码:

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  

this code is mainly to set the timer in OpenCV.这段代码主要是在OpenCV中设置定时器。

  • Here I m using datetime library.我在这里使用日期时间库。 And the duration is 5 seconds and if you want a different duration you can change the duration = 5 to your choice.持续时间为 5 秒,如果您想要不同的持续时间,您可以将duration = 5更改为您的选择。
  • I m using two while loops, the outer is for the mainframe and the inner is for the duration.我使用了两个 while 循环,外部用于大型机,内部用于持续时间。
  • Concept of timer is simple diff = (datetime.now() - start_time).seconds .计时器的概念很简单diff = (datetime.now() - start_time).seconds We just need to subtract the started time from the current time and convert the milliseconds into seconds with the help of .seconds .我们只需要从当前时间中减去开始时间,并在.seconds的帮助下将毫秒转换为秒。
  • In the second while loop while( diff <= duration ): if the diff is lower than the duration then it will print how much time is left on the frame by using this function cv2.putText() .在第二个 while 循环中while( diff <= duration ):如果diff低于持续时间,那么它将使用此函数cv2.putText()打印帧上剩余的时间。

Note:笔记:

  • Press r to reset the time and press q to quitr重置时间,按q退出

code starts here代码从这里开始

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM