Как показать запястье левой или правой руки?

#python #mediapipe

Вопрос:

Я хотел бы показать координаты запястья левой руки, если я покажу свою левую руку, или координаты запястья правой руки, если я покажу свою правую руку. Я реализовал его, но он будет отображаться только в том случае, если моя веб-камера сможет видеть обе руки. Что не так в моем коде? Я использую mediapipe и opencv в качестве фреймворка.

 with mp_holistic.Holistic(min_detection_confidence=0.5, min_tracking_confidence=0.5) as holistic:
    while cap.isOpened():
        ret, frame = cap.read()

        image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        image.flags.writeable = False
        results = holistic.process(image)
        image.flags.writeable = True
        image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

        mp_drawing.draw_landmarks(image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS )
        mp_drawing.draw_landmarks(image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)

        try:
            wrist_left_x = results.left_hand_landmarks.landmark[0].x
            wrist_left_y = results.left_hand_landmarks.landmark[0].y

            wrist_right_x = results.right_hand_landmarks.landmark[0].x
            wrist_right_y = results.right_hand_landmarks.landmark[0].y

            if results.left_hand_landmarks:
                text = wrist_left_x
                text2 = wrist_left_y

            if results.right_hand_landmarks:
                text = wrist_right_x
                text2 = wrist_right_y

            cv2.putText(image, str(text), (30, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1,
                        cv2.LINE_AA)
            cv2.putText(image, str(text2), (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 1,
                        cv2.LINE_AA)
        except:
            pass
 

Ответ №1:

Как правило, вы должны стараться избегать использования простого except предложения, когда это возможно, так как вы незаметно поймаете любую ошибку, которая возникает в try блоке. Вместо этого вы должны улавливать только те исключения, которые, как вы ожидаете, могут возникнуть при обычном выполнении.

Я подозреваю, основываясь на просмотре источника MediaPipe, что здесь происходит то, что при обнаружении только одной руки значение results.{left|right}_hand_landmarks для руки, которая не обнаружена, равно None . Поскольку это None ложное значение, ваши if results.left_hand_landmarks: и if results.right_hand_landmarks: охранники являются хорошей практикой*, но проблема в том, что вы пытаетесь получить доступ к атрибутам этих объектов за пределами охранников, а именно здесь:

         try:
            wrist_left_x = results.left_hand_landmarks.landmark[0].x
            wrist_left_y = results.left_hand_landmarks.landmark[0].y

            wrist_right_x = results.right_hand_landmarks.landmark[0].x
            wrist_right_y = results.right_hand_landmarks.landmark[0].y
 

В Python, если эти объекты есть None , это вызовет ошибку:

 AttributeError: 'NoneType' object has no attribute 'left_hand_landmarks'
 

Попробуйте переписать код на этот:

         try:
            if results.left_hand_landmarks:
                text = results.left_hand_landmarks.landmark[0].x
                text2 = results.left_hand_landmarks.landmark[0].y

            if results.right_hand_landmarks:
                text = results.right_hand_landmarks.landmark[0].x
                text2 = results.right_hand_landmarks.landmark[0].y
 

*Наилучшей практикой было бы явно использовать None проверку: if x is not None: . Поскольку у каждого типа в Python может быть свой способ определения его истинностного значения, полагаться только на то if x: , чтобы убедиться в существовании объекта, может быть ловушкой.