簡體   English   中英

在這個網絡攝像頭閱讀循環中,我如何對事件發生后經過的一定時間做出反應?

[英]How do I react to a certain amount of time having elapsed since an event, in this webcam reading loop?

目的我正在制作一個姿勢檢測系統,它可以檢測一條腿是否彎曲,並通過擴展計算完成的 Reps(成功的代表是腿彎曲 8 秒)。 我這樣做是通過使用媒體 pipe 姿勢 model,通過計算左腳踝、左膝和左臀部(地標)之間的角度。

目的是在角度小於 140 度時立即運行 8 秒的倒數計時器。

我嘗試了以下方法,我試圖修復此問題 2 天,但似乎無法做到。

import cv2
import numpy as np
import mediapipe as mp
from datetime import timedelta, datetime

mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose



# Capturing/ Reading the video
cap = cv2.VideoCapture('C:/Users/ausaf/Downloads/KneeBendVideo.mp4')

counter = 0
stage = None
diff = 0


def calculate_angle(h, k, a):  # h=hip, k=knee, a=ankle
    h = np.array(h)  # hip
    k = np.array(k)  # knee
    a = np.array(a)  # ankle

    radians = np.arctan2(h[1] - k[1], a[0] - k[0]) - np.arctan2(h[1] - k[1], h[0] - k[0])
    angle = np.abs(radians * 180.0 / np.pi)

    #     if angle > 180:
    #         angle = 360 - angle

    return angle


# # Setup Mediapipe Instance
with mp_pose.Pose(min_detection_confidence=0.8, min_tracking_confidence=0.5) as pose:
    while cap.isOpened():
        ret, frame = cap.read()
        # Recolor Image to RGB
        image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        image.flags.writeable = False

        # Make Detection
        results = pose.process(image)

        # Recolor back to BGR
        image.flags.writeable = True
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

        # Extract Landmarks
        try:
            landmarks = results.pose_landmarks.landmark

            # Get Co-ordinates

            hip = [landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].x,  landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].y]
            knee = [landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].x,
                    landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].y]
            ankle = [landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].x,
                     landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].y]

            # Calculate Angle
            angle = calculate_angle(hip, knee, ankle)
            # print(calculate_angle(hip,knee,ankle))

            # visualize
            cv2.putText(image, str(angle),
                        tuple(np.multiply(knee, [854, 640]).astype(int)),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
        except:
            pass

        # Render Rep Counter
        # Counter Box
        cv2.rectangle(image, (0, 0), (225, 73), (245, 117, 16), -1)

        # print Rep Counter to window
        cv2.putText(image, 'REPS', (15, 12),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
        cv2.putText(image, str(counter), (10, 60),
                    cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 2, cv2.LINE_AA)

        # print Knee Bent Status
        cv2.putText(image, 'Knee Status', (65, 12),
                     cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1, cv2.LINE_AA)
        cv2.putText(image, stage, (60, 60),
                     cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 2, cv2.LINE_AA)

        # Render Detections
        mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
                                  mp_drawing.DrawingSpec(color=(245, 117, 66), thickness=2, circle_radius=2),
                                  mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2), )


        # Logic for rep counting **This is the problem**
        if angle > 140:
            stage = 'straight knee'
            
        while angle < 140 and stage == 'straight knee':
            # start timer, take current time
            start_time = datetime.now()
            stage = 'bent knee'
            diff = (datetime.now() - start_time).seconds

            # check if diff == 8
            while diff <= 8 :
                # print diff to putText
                cv2.putText(image, str(diff), (70, 70),
                            cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 2, cv2.LINE_AA)
                diff = (datetime.now() - start_time ).seconds
                print(diff)
            # if the timer hits 8 seconds, increase rep count
            counter = +1
            
        # if the timer is not 0 and the angle becomes greater than 140 degrees (not bent), print feedback to window
        if angle > 140 and diff > 0:
            cv2.putText(image, 'keep your knees bent', (50, 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 2, cv2.LINE_AA)

        cv2.imshow('Mediapipe Feed', image)

        if cv2.waitKey(10) & 0xFF == ord('q'):
            break

cap.release()
cv2.destroyAllWindows()

但是,此代碼倒計時 8 秒(我通過在控制台上打印“diff”知道這一點),但視頻 output 在執行時凍結了 8 秒。 我將不勝感激任何幫助。

您僅在 8 秒后退出此循環,並且在此期間您永遠不會顯示更新的圖像(並且您不會從相機中抓取它)。

while diff <= 8 :
        # print diff to putText
        cv2.putText(image, str(diff), (70, 70),
                    cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 2, cv2.LINE_AA)
        diff = (datetime.now() - start_time ).seconds
        print(diff)

您需要在 diff start_time=None旁邊創建 scope,然后用以下代碼替換這兩個while

if angle < 140 and stage == 'straight knee':
    # start timer, take current time
    start_time = datetime.now()
    stage = 'bent knee'

if start_time and stage == 'bent knee':
        diff = (datetime.now() - start_time ).seconds
        if diff <= 8:
            cv2.putText(image, str(diff), (70, 70),
                        cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 0, 0), 2, cv2.LINE_AA)
            print(diff)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM