Reputation: 11
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.
Upvotes: 0
Views: 5576
Reputation: 92
this code is mainly to set the timer in OpenCV.
duration = 5
to your choice.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
.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()
.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()
Upvotes: 1
Reputation: 1205
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
Upvotes: 0