如何在其余代码运行而不停止的情况下每隔 x 秒打印一次?
How to print every x seconds while rest of code runs without being stopped?
我已经看到了使用 time.sleep() 函数的方法,但是这会停止 运行ning 中的其余代码。
我正在制作手部识别脚本,希望视频输出受到每秒打印的特定值的阻碍。
这是我的代码:
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()
问题是因为:
print(length)
time.sleep(1)
视频的帧率降低到1fps。
有没有办法运行打印命令不影响帧率?
谢谢。
编辑
这是新代码,我电脑上的 fps 仍然很低。
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()
一种方法是使用 time.time
来测量经过了多少时间(将每 5 秒左右打印一次 'hi',这不太精确,因为如果循环的某些部分花费更多时间, 它可能会比预期晚打印):
import time
start = time.time()
while True:
# run some code
current_time = time.time()
if current_time - start >= 5:
print('hi')
start = current_time
或者使用threading
模块并发运行一个循环(每5秒会打印'hi',这样也更精确,因为时间测量不受速度影响“主”循环(与上述代码相同):
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
我已经看到了使用 time.sleep() 函数的方法,但是这会停止 运行ning 中的其余代码。
我正在制作手部识别脚本,希望视频输出受到每秒打印的特定值的阻碍。
这是我的代码:
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()
问题是因为:
print(length)
time.sleep(1)
视频的帧率降低到1fps。
有没有办法运行打印命令不影响帧率?
谢谢。
编辑
这是新代码,我电脑上的 fps 仍然很低。
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()
一种方法是使用 time.time
来测量经过了多少时间(将每 5 秒左右打印一次 'hi',这不太精确,因为如果循环的某些部分花费更多时间, 它可能会比预期晚打印):
import time
start = time.time()
while True:
# run some code
current_time = time.time()
if current_time - start >= 5:
print('hi')
start = current_time
或者使用threading
模块并发运行一个循环(每5秒会打印'hi',这样也更精确,因为时间测量不受速度影响“主”循环(与上述代码相同):
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