[Алгоритмы, Обработка изображений, Машинное обучение] Определение позы для нескольких людей с Mediapipe

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
13-Июл-2021 19:31

Привет Хабр! Давно не писал! Сегодня определим позы нескольких людей с Mediapipe. Существует множество доступных программ для оценки позы, таких как OpenPose , MediaPipe , PoseNet и т. Д. Хотя OpenPose и PoseNet могут поддерживать оценку позы нескольких человек в реальном времени, Mediapipe может поддерживать оценку позы только одного человека. Современные подходы в основном опираются на мощные среды рабочего стола для вывода, в то время как метод Mediapipe способен обеспечить производительность в реальном времени на большинстве современных мобильных телефонов, настольных компьютеров и в Интернете(javascript).Кое-что об оценке позы Mediapipe
Функция MediaPipe Pose Landmark может извлекать 33 ключевые точки ориентира, как показано выше. Результатом является список ориентиров позы, и каждый ориентир состоит из координат ориентира x и y, нормализованных [0.0, 1.0]по ширине и высоте изображения соответственно.Образец кода
import cv2
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_holistic = mp.solutions.holistic
# For static images:
IMAGE_FILES = []
with mp_holistic.Holistic(
    static_image_mode=True,
    model_complexity=2) as holistic:
  for idx, file in enumerate(IMAGE_FILES):
    image = cv2.imread(file)
    image_height, image_width, _ = image.shape
    # Convert the BGR image to RGB before processing.
    results = holistic.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    if results.pose_landmarks:
      print(
          f'Nose coordinates: ('
          f'{results.pose_landmarks.landmark[mp_holistic.PoseLandmark.NOSE].x * image_width}, '
          f'{results.pose_landmarks.landmark[mp_holistic.PoseLandmark.NOSE].y * image_height})'
      )
    # Draw pose, left and right hands, and face landmarks on the image.
    annotated_image = image.copy()
    mp_drawing.draw_landmarks(
        annotated_image, results.face_landmarks, mp_holistic.FACE_CONNECTIONS)
    mp_drawing.draw_landmarks(
        annotated_image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
    mp_drawing.draw_landmarks(
        annotated_image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
    mp_drawing.draw_landmarks(
        annotated_image, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS)
    cv2.imwrite('/tmp/annotated_image' + str(idx) + '.png', annotated_image)
    # Plot pose world landmarks.
    mp_drawing.plot_landmarks(
        results.pose_world_landmarks, mp_holistic.POSE_CONNECTIONS)
# For webcam input:
cap = cv2.VideoCapture(0)
with mp_holistic.Holistic(
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5) as holistic:
  while cap.isOpened():
    success, image = cap.read()
    if not success:
      print("Ignoring empty camera frame.")
      # If loading a video, use 'break' instead of 'continue'.
      continue
    # Flip the image horizontally for a later selfie-view display, and convert
    # the BGR image to RGB.
    image = cv2.cvtColor(cv2.flip(image, 1), cv2.COLOR_BGR2RGB)
    # To improve performance, optionally mark the image as not writeable to
    # pass by reference.
    image.flags.writeable = False
    results = holistic.process(image)
    # Draw landmark annotation on the image.
    image.flags.writeable = True
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
    mp_drawing.draw_landmarks(
        image, results.face_landmarks, mp_holistic.FACE_CONNECTIONS)
    mp_drawing.draw_landmarks(
        image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
    mp_drawing.draw_landmarks(
        image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
    mp_drawing.draw_landmarks(
        image, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS)
    cv2.imshow('MediaPipe Holistic', image)
    if cv2.waitKey(5) & 0xFF == 27:
      break
cap.release()
Если мы намереваемся определить позы двух человек на фотографии или на видео, одним из возможных подходов было определение граничной рамки человека, наложить маску на картинку(как на нижнем рисунке), кроме граничной рамки человека, повторить это действие для других найденных людей, и по очереди дать картинку в mediapipe.
Обнаружение людей через YOLO v4 YOLO  - это современная система обнаружения объектов в реальном времени. Что то еще надо дописать. Поскольку YOLO доказал свою высокую скорость и точность, его можно использовать для обнаружения объекта-человека. Реализацию YOLOv4 взял от сюда. И добавил в демонстрационный файл несколько строчек кода и вызывал эту функцию после детекции объектов:
# MediaPipe init.
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_holistic = mp.solutions.holistic
holistic = mp_holistic.Holistic(static_image_mode=True)
def mdp_holistic(original_image, image):
    ''' MediaPipe Pose recognition. '''
    results = holistic.process(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    # cv2.imwrite('holistic_input.jpg', image)
    if results.pose_landmarks:
        # Draw pose, left and right hands, and face landmarks on the image.
        mp_drawing.draw_landmarks(
            original_image, results.face_landmarks, mp_holistic.FACE_CONNECTIONS)
        mp_drawing.draw_landmarks(
            original_image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
        mp_drawing.draw_landmarks(
            original_image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
        mp_drawing.draw_landmarks(
            original_image, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS)
    return original_image

Другое решение этой проблемыВыше, для обнаружения людей, мы использовали нейронную сеть YOLO v4, которая не самая простая и легкая. Мы еще по экспериментировали с mediapipe, и нашли выход одновременно обнаружить несколько поз людей, используя только mediapipe. Она реализована на рекурсии и не использует сторонние нейронные сети, так что она легкая и простая.Логика здесь такая, делаем копию входного изображения, находим позу первого человека, определяем максимум и минимум точки и закрашиваем этот прямоугольник, дальше ищем позу второго человека и т.д. В конце рисуем на оригинальной картинке.
import cv2
import time
import mediapipe as mp
import datetime
mp_holistic = mp.solutions.holistic
holistic = mp_holistic.Holistic(static_image_mode=True)
mp_draw = mp.solutions.drawing_utils
def holistic_recursive(origin_image, image, padding = 20, recursion_depth = 20):
    results = holistic.process(image)
    X , Y = [], []
    h, w = image.shape[:2]
    person_detected = False
    if results.pose_landmarks:
        mp_draw.draw_landmarks(origin_image, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS)
        for i in range(len(results.pose_landmarks.landmark)):
            X.append(results.pose_landmarks.landmark[i].x)
            Y.append(results.pose_landmarks.landmark[i].y)
        person_detected = True
    if results.face_landmarks:
        mp_draw.draw_landmarks(origin_image, results.face_landmarks, mp_holistic.FACE_CONNECTIONS)
        for i in range(len(results.face_landmarks.landmark)):
            X.append(results.face_landmarks.landmark[i].x)
            Y.append(results.face_landmarks.landmark[i].y)
        person_detected = True
    if results.left_hand_landmarks:
        mp_draw.draw_landmarks(origin_image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
        for i in range(len(results.left_hand_landmarks.landmark)):
            X.append(results.left_hand_landmarks.landmark[i].x)
            Y.append(results.left_hand_landmarks.landmark[i].y)
        person_detected = True
    if results.right_hand_landmarks:
        mp_draw.draw_landmarks(origin_image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
        for i in range(len(results.right_hand_landmarks.landmark)):
            X.append(results.right_hand_landmarks.landmark[i].x)
            Y.append(results.right_hand_landmarks.landmark[i].y)
        person_detected = True
    if person_detected and recursion_depth > 0:
        # create bbox
        x1 = int(min(X) * w)
        y1 = int(min(Y) * h)
        x2 = int(max(X) * w)
        y2 = int(max(Y) * h)
        # Add padding
        x1 = x1 - padding if x1 - padding > 0 else 0
        y1 = y1 - padding if y1 - padding > 0 else 0
        x2 = x2 + padding if x2 + padding < w else w
        y2 = y2 + padding if y2 + padding < h else h
        # zero bbox
        image[y1:y2, x1:x2] = 0
        # cv2.imwrite('crop.jpg', image)
        holistic_recursive(origin_image, image, recursion_depth - 1)
cap = cv2.VideoCapture(0)
# cap = cv2.VideoCapture('smeny-etsn-brigadoy-tkrs_Pxv28bmL_N5en.mp4')
# Write video
# w = int(cap.get(3))
# h = int(cap.get(4))
# fourcc = cv2.VideoWriter_fourcc(*'MP4V')
# out = cv2.VideoWriter('output_recursive.mp4', fourcc, 10.0, (w, h))
start_time = time.time()
frame_count = 0
fps = 0
while True:
    _, img = cap.read()
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    # Recursive run detection
    image = img_rgb.copy()
    holistic_recursive(img, image)
    frame_count += 1
    if frame_count > 20:
        fps = frame_count / (time.time() - start_time)
        start_time = time.time()
        frame_count = 0
    cv2.putText(img, f'FPS: {int(fps)}', (10, 30), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 0), 2)
    cv2.imshow("cam", img)
    # out.write(img)
    k = cv2.waitKey(1)
    if k == 27:  # close on ESC key
        break
# cap.release()
# out.release()
cv2.destroyAllWindows()

В этой реализации с помощью Mediapipe мы достигли позы с несколькими людьми. Надеюсь, вы найдете это полезным для работы или учебы. Оценка позы человека из видео применяется в различных приложениях, таких как распознавание языка жестов и управление жестами всего тела. Существуют также применения в классификации последовательности движений при физической активности, такой как йога, упражнения и танцы, что позволяет количественно определять движения с помощью определения ориентиров на теле.
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_algoritmy (Алгоритмы), #_obrabotka_izobrazhenij (Обработка изображений), #_mashinnoe_obuchenie (Машинное обучение), #_mediapipe, #_yolov4, #_pose_estimation, #_detection, #_algoritmy (
Алгоритмы
)
, #_obrabotka_izobrazhenij (
Обработка изображений
)
, #_mashinnoe_obuchenie (
Машинное обучение
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 01-Июн 11:38
Часовой пояс: UTC + 5