赞
踩
大约两年前,基于自己的理解我曾写了几篇关于Mediapipe的文章,似乎帮助到了一些人。这两年,忙于比赛、实习、毕业、工作和考研。上篇文章已经是一年多前发的了。这段时间收到很多私信和评论,请原谅无法一一回复了。我将尝试在这篇文章里回答一些大家经常问到的问题。
我曾在之前的文章里讲过,可以使用Mediapipe推理得到的3d坐标绘制到3d画布上,使用的函数就是:mp.solutions.drawing_utils.plot_landmarks(),不过只能导出2d图,没法拖动交互,实现效果如下:
这个函数是官方自己封装的,我们可以利用matplotlib自行实现实时绘制3d铰接骨架图的需求,效果如下:
实时姿态估计
mediapipe可以推理得到3d坐标,但这个3d坐标并不是真实的3d坐标。这些坐标描述了一个以人体臀部为中心的人体外接圆,是虚拟的坐标。这一点可以从其官方描述得知。
在对每一帧图像做处理时,如果要获取某个keypoint(人体某个关节)在图像上的坐标时,可以这样转换:
results = pose.process(img)
X_ = results.pose_landmarks.landmark[mp_pose.PoseLandmark.NOSE].x * img_width
Y_ = results.pose_landmarks.landmark[mp_pose.PoseLandmark.NOSE].y * img_height
要结束程序,请按ESC,或者ctrl+c
import cv2 import matplotlib.pyplot as plt import mediapipe as mp import time import numpy as np mp_pose = mp.solutions.pose mp_drawing = mp.solutions.drawing_utils mp_drawing_styles = mp.solutions.drawing_styles colorclass = plt.cm.ScalarMappable(cmap='jet') colors = colorclass.to_rgba(np.linspace(0, 1, int(33))) colormap = (colors[:, 0:3]) def draw3d(plt, ax, world_landmarks, connnection=mp_pose.POSE_CONNECTIONS): ax.clear() ax.set_xlim3d(-1, 1) ax.set_ylim3d(-1, 1) ax.set_zlim3d(-1, 1) landmarks = [] for index, landmark in enumerate(world_landmarks.landmark): landmarks.append([landmark.x, landmark.z, landmark.y*(-1)]) landmarks = np.array(landmarks) ax.scatter(landmarks[:, 0], landmarks[:, 1], landmarks[:, 2], c=np.array(colormap), s=50) for _c in connnection: ax.plot([landmarks[_c[0], 0], landmarks[_c[1], 0]], [landmarks[_c[0], 1], landmarks[_c[1], 1]], [landmarks[_c[0], 2], landmarks[_c[1], 2]], 'k') plt.pause(0.001) #端口号一般是0,除非你还有其他摄像头 #使用本地视频推理,复制其文件路径代替端口号即可 cap = cv2.VideoCapture(0) with mp_pose.Pose( min_detection_confidence=0.5, min_tracking_confidence=0.5, model_complexity = 1) as pose: fig = plt.figure() ax = fig.add_subplot(111, projection="3d") 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 # To improve performance, optionally mark the image as not writeable to # pass by reference. start = time.time() image.flags.writeable = False image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = pose.process(image) # Draw the pose annotation on the image. image.flags.writeable = True image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) mp_drawing.draw_landmarks( image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS, landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style()) end = time.time() fps = 1 / (end - start) fps = "%.2f fps" % fps #实时显示帧数 image = cv2.flip(image, 1) cv2.putText(image, "FPS {0}".format(fps), (100, 50), cv2.FONT_HERSHEY_SIMPLEX, 0.75, (255, 255, 255),3) cv2.imshow('MediaPipe Pose', image) if cv2.waitKey(5) & 0xFF == 27: break if results.pose_world_landmarks: draw3d(plt, ax, results.pose_world_landmarks) cap.release()
如果有任何问题,欢迎在评论区讨论、赐教。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。