I am trying to get multiple people to draw landmarks using MediaPipe’s Pose with Python3.10.14, but it does not work. The program is forced to exit without error. In other words, it is not trapped by “except” in the code. The following is a code which always fails at detection_result = detector.detect_async(...)
line.
import mediapipe as mp
from mediapipe.tasks import python
from mediapipe.tasks.python import vision
from mediapipe import solutions
from mediapipe.tasks.python.vision.pose_landmarker import PoseLandmarkerResult
import cv2
import time
import numpy as np
def print_result(result: mp.tasks.vision.PoseLandmarkerResult, output_image: mp.Image, timestamp_ms: int):
pose_landmarks_list = result.pose_landmarks
annotated_image = output_image.numpy_view()
for pose_landmarks in pose_landmarks_list:
solutions.drawing_utils.draw_landmarks(
annotated_image,
pose_landmarks,
mp.solutions.pose.POSE_CONNECTIONS,
landmark_drawing_spec=solutions.drawing_styles.get_default_pose_landmarks_style())
print('pose landmarker result: {}'.format(annotated_image))
def init_detector(task_name):
model_path = f"./models/{task_name}"
# STEP 2: Create an PoseLandmarker object.
base_options = python.BaseOptions(model_asset_path=model_path)
VisionRunningMode = mp.tasks.vision.RunningMode
options = vision.PoseLandmarkerOptions(
base_options=base_options,
running_mode=VisionRunningMode.LIVE_STREAM, # VisionRunningMode.LIVE_STREAM, VisionRunningMode.IMAGE
result_callback=print_result,
num_poses=3, # 1,
min_pose_detection_confidence=0.5,
min_pose_presence_confidence=0.5,
min_tracking_confidence=0.5,
output_segmentation_masks=False)
return options
def draw_landmarks_on_image(rgb_image, detection_result):
pose_landmarks_list = detection_result.pose_landmarks
annotated_image = np.copy(rgb_image)
# Loop through the detected poses to visualize.
for idx in range(len(pose_landmarks_list)):
pose_landmarks = pose_landmarks_list[idx]
# Draw the pose landmarks.
solutions.drawing_utils.draw_landmarks(
annotated_image,
pose_landmarks,
mp.solutions.pose.POSE_CONNECTIONS,
solutions.drawing_styles.get_default_pose_landmarks_style())
return annotated_image
def main():
video_path = "./mp4/my_movie.mp4"
cap = cv2.VideoCapture(video_path)
# if not cap.isOpened():
# print("Failed to open video file.")
# exit()
print('selected')
cv2.namedWindow("Video", cv2.WINDOW_AUTOSIZE) # WINDOW_AUTOSIZE WINDOW_NORMAL WINDOW_FULLSCREEN
options = init_detector('pose_landmarker_lite.task')
detector = vision.PoseLandmarker.create_from_options(options)
pTime = 0
cTime = 0
timestamp = 0
while True:
time.sleep(0.01)
success, img = cap.read()
if not success:
break
# Convert the frame received from OpenCV to a MediaPipe’s Image object.
mp_image = mp.Image(image_format=mp.ImageFormat.SRGB, data=img)
# prevent overflow
fps = cap.get(cv2.CAP_PROP_FPS)
timestamp += 1000 / fps
try:
detection_result = detector.detect_async(mp_image, int(timestamp)) ## <- Always failed w/o any error!!
except Exception as e:
print(f"Error during detection: {e}")
break
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
cv2.putText(img, str(int(fps)), (10, 100), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 255), 3)
# Draw the landmarks if the detection result is available.
if isinstance(detection_result, PoseLandmarkerResult):
annotated_image = draw_landmarks_on_image(img, detection_result)
cv2.imshow("Video", annotated_image)
else:
cv2.imshow("Video", img)
key = cv2.waitKey(1)
# Press esc or 'q' to close the image window
if key & 0xFF == ord('q') or key == 27:
cv2.destroyAllWindows()
break
cap.release()
cv2.destroyAllWindows()
if __name__=="__main__":
main()
The official MediaPipe site has a sample code for a image file, and I have confirmed that adding num_poses=3 in that code, as shown below, will overlay the landmark on multiple people.
options = vision.PoseLandmarkerOptions(
base_options=base_options,
num_poses=3,
output_segmentation_masks=True)
I used a movie file from here.
Please tell me how to fix it.
Thank you.