Только ориентиры Mediapipe Display Body

Я установил Mediapipe (0.9.0.1) с помощью Python (3.7.0) в Windows 11. Мне удалось заставить Mediapipe генерировать ориентиры (для лица и тела); для изображения, видео и потока веб-камеры.

Теперь я хотел бы, чтобы Mediapipe рисовал только ориентиры, характерные для тела (т. Е. Исключая лицевые ориентиры).

Я понимаю, что могу использовать OpenCV (или Czone) для достижения этой цели, однако я хочу достичь своей цели, используя Mediapipe (т. е. используя функцию draw_landmarks в библиотеке MediaPipe).

Конкретный фрагмент кода, который я пытаюсь (но с ошибками), выглядит следующим образом:

#Initialize a list to store the detected landmarks.
    landmarks = []

    # Iterate over the Mediapipe detected landmarks.
    for landmark in results.pose_landmarks.landmark:
        
        # Append the Mediapipe landmark into the list.
        landmarks.append((int(landmark.x * width), int(landmark.y * height),
                                (landmark.z * width)))
    
    #create index list for specific landmarks 
    body_landmark_indices = [11,12,13,14,15,16,23,24,25,26,27,28,29,30,31,32]

    landmark_list_body = []

    #Create a list which only has the required landmarks
    for index in body_landmark_indices:
        landmark_list_body.append(landmarks[index - 1])

    mp_drawing.draw_landmarks(
                        image=output_image,
                        landmark_list=landmark_list_body.pose_landmarks,
                        connections=mp_pose.POSE_CONNECTIONS,
                        landmark_drawing_spec=landmark_drawing_spec,
                        connection_drawing_spec=connection_drawing_spec)`

Executing the above I get the error `'list' object has no attribute 'pose_landmarks'

Я заменил landmark_list=landmark_list_body.pose_landmarks, на landmark_list=landmark_list_body, но с ошибками.

Я теперь очень tiered и из идей. Есть ли герой без плаща?

Спасибо.

Кто-нибудь может предложить несколько предложений? Могу ли я поделиться более подробной информацией, которая может помочь? Спасибо.

Ghulam 10.02.2023 15:56
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
100
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете попробовать следующий подход:

import cv2
import mediapipe as mp
import numpy as np
from mediapipe.python.solutions.pose import PoseLandmark
from mediapipe.python.solutions.drawing_utils import DrawingSpec
mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_pose = mp.solutions.pose


custom_style = mp_drawing_styles.get_default_pose_landmarks_style()
custom_connections = list(mp_pose.POSE_CONNECTIONS)

# list of landmarks to exclude from the drawing
excluded_landmarks = [
    PoseLandmark.LEFT_EYE, 
    PoseLandmark.RIGHT_EYE, 
    PoseLandmark.LEFT_EYE_INNER, 
    PoseLandmark.RIGHT_EYE_INNER, 
    PoseLandmark.LEFT_EAR,
    PoseLandmark.RIGHT_EAR,
    PoseLandmark.LEFT_EYE_OUTER,
    PoseLandmark.RIGHT_EYE_OUTER,
    PoseLandmark.NOSE,
    PoseLandmark.MOUTH_LEFT,
    PoseLandmark.MOUTH_RIGHT ]

for landmark in excluded_landmarks:
    # we change the way the excluded landmarks are drawn
    custom_style[landmark] = DrawingSpec(color=(255,255,0), thickness=None) 
    # we remove all connections which contain these landmarks
    custom_connections = [connection_tuple for connection_tuple in custom_connections 
                            if landmark.value not in connection_tuple]


IMAGE_FILES = ["test.jpg"]
BG_COLOR = (192, 192, 192) 
with mp_pose.Pose(
    static_image_mode=True,
    model_complexity=2,
    enable_segmentation=True,
    min_detection_confidence=0.5) as pose:
    for idx, file in enumerate(IMAGE_FILES):
        image = cv2.imread(file)
        image_height, image_width, _ = image.shape
        results = pose.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
        annotated_image = image.copy()

        mp_drawing.draw_landmarks(
            annotated_image,
            results.pose_landmarks,
            connections = custom_connections, #  passing the modified connections list
            landmark_drawing_spec=custom_style) # and drawing style 

        cv2.imshow('landmarks', annotated_image)
        cv2.waitKey(0)

Он изменяет DrawingSpec и POSE_CONNECTIONS, чтобы «скрыть» подмножество ориентиров. Однако из-за того, как функция draw_landmarks() реализована в Mediapipe, также необходимо добавить условие в drawing_utils.py (находится в site-packages/mediapipe/python/solutions):

if drawing_spec.thickness == None: continue

Добавьте его перед строкой 190 (# White circle border). Результат должен выглядеть так:

...
      drawing_spec = landmark_drawing_spec[idx] if isinstance(
          landmark_drawing_spec, Mapping) else landmark_drawing_spec
      if drawing_spec.thickness == None: continue
      # White circle border
      circle_border_radius = max(drawing_spec.circle_radius + 1,
                                 int(drawing_spec.circle_radius * 1.2))
...

Это изменение необходимо для того, чтобы полностью исключить белую рамку, нарисованную вокруг ориентиров, независимо от спецификации их чертежа.

Надеюсь, поможет.

Простого принятия вашего ответа недостаточно. Ваше решение работает отлично, и предоставленные шаги были кристально ясными. Я вижу, что [в настоящее время] у вас есть ограниченное количество вкладов и, следовательно, связанных рейтингов / значков; но вы действительно тот, кто может многое предложить. Я желаю вам всего наилучшего и благодарю вас за время и усилия, которые вы потратили на поиск решения. Это очень ценится.

Ghulam 12.02.2023 23:28

Спасибо за приятные слова, только решил попробовать начать отвечать на вопросы :) Удачи и буду рад попробовать и помочь, если нужно адаптировать приложенный код под вашу задачу.

Stefan 13.02.2023 09:54

Другие вопросы по теме