python - 如何在其余代码运行而不停止的情况下每隔 x 秒打印一次?

标签 python opencv cvzone

我已经看到了使用 time.sleep() 函数的方法,但是这会阻止其余代码运行。

我正在制作手部识别脚本,并希望视频输出受到每秒打印的特定值的阻碍。

这是我的代码:

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

关于python - 如何在其余代码运行而不停止的情况下每隔 x 秒打印一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70544320/

相关文章:

python-2.7 - 如果使用 python 和 opencv 在两个目录之间检测到公共(public)面孔,如何通知用户

python - "Can' t 初始化字符集utf8mb4"with Windows mysql-python

python - PyPI 区分大小写吗?

python - Numpy 中的高级索引

python - 使用scipy.optimize时如何处理 'residues are not finite in the initial point'?

python - 将tensorflow object detection api与opencv的centroid tracking算法集成

python - 使用 Opencv 关闭 python 代码后如何保存轨迹栏值?