简体   繁体   中英

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

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.

  • 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.
  • I m using two while loops, the outer is for the mainframe and the inner is for the duration.
  • Concept of timer is simple 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 .
  • 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() .

Note:

  • Press r to reset the time and press q to quit

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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