重磅干货,第一时间送达 人体姿态估计是一个非常有趣的领域,如果我们能够将诸如棒球摆动或投球等运动的人体姿势量化为数据,那么我们或许能够将数据转化为有用的见解,例如伤害预防或高级训练。 有一些开源人体姿态估计,例如PoseNet和OpenPose,OpenPose 由 CMU 团队开发并得到广泛应用。 OpenPose 团队使用两个不同的数据集提供了两个预训练模型:多人数据集 (MPII) 和 COCO 数据集。COCO 模型产生 18 个点,MPII 模型产生 15 个点,我们将在这项工作中使用 MPII。 设置模型首先,我们需要下载模型并将其保存到项目文件夹中。 protoFile = "openpose/mpi/pose_deploy_linevec_faster_4_stages.prototxt" weightsFile = "openpose/mpi/pose_iter_160000.caffemodel" 然后我们使用OpenCV的dnn模块来加载模型; net = cv2.dnn.readNetFromCaffe(protoFile, weightsFile) 阅读视频然后我们使用OpenCV逐帧读取视频: # capture video cap = cv2.VideoCapture(video_path) # Check if video file is opened successfully if (cap.isOpened() == False): print("Error opening video stream or file") # Read until video is completed while(cap.isOpened()): # Capture frame-by-frame ret, frame = cap.read() if ret == True: frame = cv2.resize(frame, (width_out, int(width_out*height/width)), cv2.INTER_AREA) # process the frame here # Break the loop else: break 分析框架在循环内部,我们需要将框架输入模型中,并使用以下方法处理结果: inpBlob = cv2.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight), (0, 0, 0), swapRB = False,crop = False) net.setInput(inpBlob) output = net.forward() 这会产生结果,然后我们需要处理它。使用Vikas Gupta的本教程中的代码,我们可以获得关键点并将其绘制在框架上。 H = out.shape[2] W = out.shape[3] # Empty list to store the detected keypoints points = [] for i in range(len()): # confidence map of corresponding body's part. probMap = output[0, i, :, :] # Find global maxima of the probMap. minVal, prob, minLoc, point = cv2.minMaxLoc(probMap) # Scale the point to fit on the original image x = (frameWidth * point[0]) / W y = (frameHeight * point[1]) / H if prob > threshold : cv2.circle(frame, (int(x), int(y)), 15, (0, 255, 255), thickness=-1, lineType=cv.FILLED) cv2.putText(frame, "{}".format(i), (int(x), int(y)), cv2.FONT_HERSHEY_SIMPLEX, 1.4, (0, 0, 255), 3, lineType=cv2.LINE_AA) # Add the point to the list if the probability is greater than the threshold points.append((int(x), int(y))) else : points.append(None) 然后我们可以连接关键点并在它们之间画线。但首先,我们需要定义如何连接这些点。基于 MPII 的关键点描述: Head – 0 Neck – 1 Right Shoulder – 2 Right Elbow – 3 Right Wrist – 4 Left Shoulder – 5 Left Elbow – 6 Left Wrist – 7 Right Hip – 8 Right Knee – 9 Right Ankle – 10 Left Hip – 11 Left Knee – 12 Left Ankle – 13 Chest – 14 Background – 15 我们可以定义这一对: POSE_PAIRS = [[0,1], [1,2], [2,3], [3,4], [1,5], [5,6], [6,7], [1,14] , [14,8], [8,9], [9,10], [14,11], [11,12], [12,13] ] 然后,我们可以简单地使用 OpenCV 绘制线: for pair in POSE_PAIRS: partA = pair[0] partB = pair[1] if points[partA] and points[partB]: cv2.line(frameCopy, points[partA], points[partB], (0, 255, 0), 3) 视频输出我们也可以使用 OpenCV 输出视频,只需创建一个视频编写器。 out = cv2.VideoWriter(out_path + '/' + out_name + '.webm', cv2.VideoWriter_fourcc(*'VP90'), FPS, size_out) 并在循环中调用 out.write(frame) ,最后调用 out.release()。 也就是说,现在这个程序能够读取视频并使用 OpenPose 在帧上绘制骨架,并将结果输出为视频。 如果我们为用户提供一个简单的用户界面会更方便。Streamlit 是一个强大的工具,可以在没有 Web 开发技能的情况下创建 Web 应用程序。 下载模型这个应用程序的第一件事是下载模型。因为模型太大(>200MB),不方便推送到 Github 或者直接推送到 Heroku 。因此,我们需要应用程序从外部 url 下载文件,以确保模型已准备就绪。 我们可以将模型存储在我们的保管箱帐户中,并创建一个可下载的链接。 EXTERNAL_DEPENDENCIES = { “openpose/coco/pose_iter_440000.caffemodel”:{ "url": "https://dl./s/xxxxx/pose_iter_440000.caffemodel?dl=0", “大小”:209274056} } 然后我们使用 Streamlit 演示(https://github.com/streamlit/streamlit)中的代码来创建带有进度条的下载功能。 我们可以调用函数并下载模型 for filename in EXTERNAL_DEPENDENCIES.keys(): download_file(filename) 为用户创建上传工具我们想有一个允许用户上传他们的视频进行分析的工具,Streamlit 提供了一个制作工具:st.file_uploader uploaded_file = st.file_uploader("upload a video", type=['mp4']) 然后我们将它保存到一个临时位置 if uploaded_file is not None: g = io.BytesIO(uploaded_file.read()) # BytesIO Object temporary_location = "image/temp.mp4" with open(temporary_location, 'wb') as out: # Open temporary file as bytes out.write(g.read()) # Read bytes into file # close file out.close() 分析然后我们可以修改上面提到的 OpenPose 过程,让它成为一个函数,并在按下 “分析” 按钮时调用该函数来分析上传的视频。它生成姿势估计的结果和带有人体姿势的视频,然后我们就可以使用 Streamlit 的视频功能将其展示在页面上。 st.video(str(path_video_out/filename/'output'/(filename+'_out'))+'.webm') 就是这样,现在我们有了一个简单的 web 应用程序,允许用户上传视频和分析人体姿势。下一步是部署应用程序,我们将尝试两个选项。 Streamlit shareStreamlit 最近推出了Streamlit share,这使得部署 Streamlit 应用程序变得非常容易。我们只需要将我们的应用程序推送到 Github,并将其连接到 Streamlit share,然后它就会负责部署。 在 Streamlit share 上运行我们的应用程序的一个缺点是它不提供 GPU 计算。然而,姿势检测的计算量非常大,需要 GPU 来加速推理时间,因此仅使用 CPU 处理视频需要相当长的时间。 Google Colab另一个选项是 Google Colab,它提供 GPU 服务,因此推理时间要快得多。但是,部署只是暂时的,当 Colab notebook 关闭(或运行超过 12 小时)时,部署会关闭。此外,它还需要更多的设置步骤。 通过获取身体运动的量化数据,可以从数据中找到见解。例如,可以计算手的速度,也可以计算摆动过程中关节之间的角度,还可以比较球员的挥杆。这些数据可能有助于高级训练和预防损伤。 |
|