Reputation: 47
I've seen ways of using the time.sleep() function, however that stops the rest of the code from running.
I'm making a hand recognition script and want the video output to be hindered by a certain value being printed every second.
This is my code:
import cv2
from cvzone.HandTrackingModule import HandDetector
import time
cap = cv2.VideoCapture(0)
detector = HandDetector(maxHands=1, detectionCon=0.7)
length = 0
while True:
success, img = cap.read()
hands, img = detector.findHands(img)
if hands:
hand1 = hands[0]
lmlist1 = hand1["lmList"]
bbox = hand1["bbox"]
cp1 = hand1["center"]
HandType = hand1["type"]
#fingers1 = detector.fingersUp(hand1)
#print(fingers1)
length, info, img = detector.findDistance(lmlist1[8], lmlist1[5], img)
print(length)
time.sleep(1)
cv2.imshow("Image", img)
cv2.waitKey(1)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
The problem is that because of:
print(length)
time.sleep(1)
the frame rate of the video is reduced to 1fps.
Is there a way to run the printing command so that it doesn't affect the frame rate?
Thanks.
EDIT
This is the new code and fps is still low on my computer.
import cv2
from cvzone.HandTrackingModule import HandDetector
import time
import threading
import math
#Resolution: 720 x 1280
cap = cv2.VideoCapture(0)
detector = HandDetector(maxHands=1, detectionCon=0.7)
length = 0
fingerpos = [1,1,1,1,1]
def index(img):
lil, info, img = detector.findDistance(lmlist1[8], lmlist1[5], img)
lib, info, img = detector.findDistance(lmlist1[6], lmlist1[5], img)
lit, info, img = detector.findDistance(lmlist1[8], lmlist1[6], img)
index_angle = (lib**2 + lit**2 - lil**2) / (2 * lib * lit)
index_angle = math.degrees(math.acos(index_angle))
return int(index_angle)
def middle(img):
lml, info, img = detector.findDistance(lmlist1[12], lmlist1[9], img)
lmb, info, img = detector.findDistance(lmlist1[12], lmlist1[10], img)
lmt, info, img = detector.findDistance(lmlist1[10], lmlist1[9], img)
middle_angle = (lmb**2 + lmt**2 - lml**2) / (2 * lmb * lmt)
middle_angle = math.degrees(math.acos(middle_angle))
return int(middle_angle)
def ring(img):
lrl, info, img = detector.findDistance(lmlist1[16], lmlist1[13], img)
lrb, info, img = detector.findDistance(lmlist1[16], lmlist1[14], img)
lrt, info, img = detector.findDistance(lmlist1[14], lmlist1[13], img)
ring_angle = (lrb**2 + lrt**2 - lrl**2) / (2 * lrb * lrt)
ring_angle = math.degrees(math.acos(ring_angle))
return int(ring_angle)
def pinky(img):
lpl, info, img = detector.findDistance(lmlist1[20], lmlist1[17], img)
lpb, info, img = detector.findDistance(lmlist1[20], lmlist1[18], img)
lpt, info, img = detector.findDistance(lmlist1[18], lmlist1[17], img)
pinky_angle = (lpb**2 + lpt**2 - lpl**2) / (2 * lpb * lpt)
pinky_angle = math.degrees(math.acos(pinky_angle))
return int(pinky_angle)
def thumb(img):
ltl, info, img = detector.findDistance(lmlist1[4], lmlist1[2], img)
ltb, info, img = detector.findDistance(lmlist1[4], lmlist1[3], img)
ltt, info, img = detector.findDistance(lmlist1[3], lmlist1[2], img)
thumb_angle = (ltb**2 + ltt**2 - ltl**2) / (2 * ltb * ltt)
thumb_angle = math.degrees(math.acos(thumb_angle))
return int(thumb_angle)
def data(img):
print(str(thumb(img)) + ", " + str(index(img)) + ", " + str(middle(img)) + ", " + str(ring(img)) + ", " + str(pinky(img)))
time.sleep(0.5)
threading.Thread(target=data).start()
while True:
success, img = cap.read()
#img = cv2.resize(img, (640, 420))
hands, img = detector.findHands(img)
#print('Resolution: ' + str(img.shape[0]) + ' x ' + str(img.shape[1]))
if hands:
hand1 = hands[0]
lmlist1 = hand1["lmList"]
bbox = hand1["bbox"]
cp1 = hand1["center"]
HandType = hand1["type"]
data(img)
#print(str(thumb(img)) + ", " + str(index(img)) + ", " + str(middle(img)) + ", " + str(ring(img)) + ", " + str(pinky(img)))
cv2.imshow("Image", img)
cv2.waitKey(1)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
Upvotes: 3
Views: 2419
Reputation: 6156
One way is to use time.time
to measure how much time has passed (will print 'hi' every 5 seconds or so, this is less precise because if some part of the loop takes more time, it may print later than expected):
import time
start = time.time()
while True:
# run some code
current_time = time.time()
if current_time - start >= 5:
print('hi')
start = current_time
Or use threading
module to run a loop concurrently (will print 'hi' every 5 seconds, this is also more precise, because the time measurement is not affected by the speed of the "main" loop (as is the case with the above code)):
import time
import threading
def loop():
while True:
time.sleep(5)
print('hi')
threading.Thread(target=loop).start()
while True:
# run some code
pass # this can be removed after you add the actual code
Upvotes: 4