基于 pytorch-openpose 实现 “多目标” 人体姿态估计

2024-01-25 07:04

本文主要是介绍基于 pytorch-openpose 实现 “多目标” 人体姿态估计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

还记得上次通过 MediaPipe 估计人体姿态关键点驱动 3D 角色模型,虽然节省了动作 K 帧时间,但是网上还有一种似乎更方便的方法。MagicAnimate 就是其一,说是只要提供一张人物图片和一段动作视频 (舞蹈武术等),就可以完成图片人物转视频。

于是我就去官网体验了一下,发现动作的视频长度不能超过 5 秒,当然,如果说要整长视频可以切多段处理再合成解决。主要的还是视频需要那种背景相对较纯的,不然提交表单一直报错,还有他也不能处理画面内多人物的姿态估计。

多目标人体姿态估计

为什么我要弄多目标,其实是我有次拿了一舞团的视频用 MediaPipe 检测,发现一个画面中只能采集到一个人的动作数据。虽然齐舞可能就一套动作,其他的角色模型可以复制粘贴,但是有些编舞为了好看,伴舞也会根据节奏作不同的变化。所以说对于我用来采集舞蹈数据,这个很重要了,当然他也可以用在多人互动的 AR 游戏,或用在同时培训多人的动作规范检测等等场景。

要从单一人体检测到多人体姿态估计,开始我是打算用 YOLO 对画面中的多 Person 区块读出来,然后再将这些方块遍历交给 MediaPipe 对指定区域作人物动作节点识别。但是最后发现有现成的算法,就是 pytorch-openpose,所以果断先用这个来体验了一下。

pytorch-openpose 简介

PyTorch-OpenPose 是一个基于 PyTorch 的开源库,它实现了 OpenPose 的功能,可以进行人的面部表情、躯干和四肢甚至手指的跟踪。它不仅适用于单人也适用于多人,同时具有较好的鲁棒性。要运行 PyTorch-OpenPose,需要安装支持 CUDA 的 PyTorch,以下例子有使用作者提供的预训练模型,通过拆分视频帧,绘制多人物动作线条保存图片,最后将图片合成为视频。

环境

  • scikit-image
  • opencv-python
  • scipy
  • matplotlib
  • numpy

编码

帧拆分绘制

import cv2
import matplotlib.pyplot as plt
import copy
import numpy as np
import torch
from src import model
from src import util
from src.body import Body
from src.hand import Handbody_estimation = Body('model/body_pose_model.pth')
hand_estimation = Hand('model/hand_pose_model.pth')print(f"Torch device: {torch.cuda.get_device_name()}")cap = cv2.VideoCapture("D:/3code/6pytorch/opencv_demo/12_open_pose/11.mp4")
cap.set(3, 640)
cap.set(4, 480)indices = 1
while True:ret, oriImg = cap.read()if not ret:breakcandidate, subset = body_estimation(oriImg)canvas = copy.deepcopy(oriImg)canvas = util.draw_bodypose(canvas, candidate, subset)# detect handhands_list = util.handDetect(candidate, subset, oriImg)all_hand_peaks = []for x, y, w, is_left in hands_list:peaks = hand_estimation(oriImg[y:y+w, x:x+w, :])peaks[:, 0] = np.where(peaks[:, 0]==0, peaks[:, 0], peaks[:, 0]+x)peaks[:, 1] = np.where(peaks[:, 1]==0, peaks[:, 1], peaks[:, 1]+y)all_hand_peaks.append(peaks)canvas = util.draw_handpose(canvas, all_hand_peaks)cv2.imwrite('image_out/img_{}.jpg'.format(indices), canvas)indices += 1print("images:", indices)# cv2.imshow('demo', canvas)#一个窗口用以显示原视频# if cv2.waitKey(1) & 0xFF == ord('q'):#     breakcap.release()
cv2.destroyAllWindows()

视频合成

from pathlib import Path
import cv2
import os# 将视频video_path分割成图片和音频文件,保存到save_path文件夹中
def video2mp3_img(video_path, save_path, audio_path):def video_split(video_path, save_path):if not os.path.exists(save_path):os.makedirs(save_path)cap = cv2.VideoCapture(video_path)i = 0while True:ret, frame = cap.read()if ret:cv2.imwrite(save_path + '/' + str(i) + '.jpg', frame)i += 1else:breakcap.release()if not os.path.exists(save_path):os.makedirs(save_path)# 视频分割video_split(video_path, save_path)# 视频转音频# os.system("ffmpeg -i {} -vn -acodec copy {}/audio.mp3".format(video_path, audio_path))os.system("ffmpeg -i {} -q:a 0 -map a {}/audio.mp3".format(video_path, audio_path))# 音频转wav# os.system("ffmpeg -i {}/audio.mp3 {}/audio.wav".format(save_path, save_path))# 将video_imgout文件夹中的图片合成视频并且添加音频文件video_img/audio.mp3
def img2mp4(image_out, save_name):BASE_PATH = os.path.dirname(__file__)# 读取img sizeimg = cv2.imread("{}/img_1.jpg".format(image_out))imgInfo = img.shapesize = (imgInfo[1], imgInfo[0])files = []for dirpath, dirnames, filenames in os.walk(image_out):for filename in filenames:fileName = Path(os.path.join(dirpath, filename))files.append(os.path.join(dirpath, filename))files = [file.replace('\\', '/') for file in files]files.sort(key=lambda x: int(x.split('/')[-1].split('.')[0].split('_')[-1]))fourcc = cv2.VideoWriter_fourcc(*'mp4v')videoWrite = cv2.VideoWriter(f'videos/{save_name}.mp4', fourcc, 25, size)  # 写入对象 1 file name  3: 视频帧率for i in files:img = cv2.imread(str(i))videoWrite.write(img)print(f'videos/{save_name}.mp4')# 将video_img中的音频文件添加到视频中# os.system("ffmpeg -i {}/videos/{}.mp4 -c:v copy -c:a aac -strict experimental {}/videos/{}.mp4".format(BASE_PATH, save_name, BASE_PATH, save_name))if __name__ == '__main__':BASE = os.path.dirname(__file__)video_path = os.path.join(BASE, "videos/yangguo.mp4")  # 视频路径save_path = os.path.join(BASE, "video_img")            # 拆解视频保存路径audio_path = os.path.join(BASE, "audio")               # 分离音频保存路径# 视频  ==> imgs# video2mp3_img(video_path, save_path, audio_path)# # imgs ==> 视频img2mp4("image_out", save_name='ldh')

这篇关于基于 pytorch-openpose 实现 “多目标” 人体姿态估计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/642448

相关文章

使用Vue-ECharts实现数据可视化图表功能

《使用Vue-ECharts实现数据可视化图表功能》在前端开发中,经常会遇到需要展示数据可视化的需求,比如柱状图、折线图、饼图等,这类需求不仅要求我们准确地将数据呈现出来,还需要兼顾美观与交互体验,所... 目录前言为什么选择 vue-ECharts?1. 基于 ECharts,功能强大2. 更符合 Vue

使用WPF实现窗口抖动动画效果

《使用WPF实现窗口抖动动画效果》在用户界面设计中,适当的动画反馈可以提升用户体验,尤其是在错误提示、操作失败等场景下,窗口抖动作为一种常见且直观的视觉反馈方式,常用于提醒用户注意当前状态,本文将详细... 目录前言实现思路概述核心代码实现1、 获取目标窗口2、初始化基础位置值3、创建抖动动画4、动画完成后

uniapp小程序中实现无缝衔接滚动效果代码示例

《uniapp小程序中实现无缝衔接滚动效果代码示例》:本文主要介绍uniapp小程序中实现无缝衔接滚动效果的相关资料,该方法可以实现滚动内容中字的不同的颜色更改,并且可以根据需要进行艺术化更改和自... 组件滚动通知只能实现简单的滚动效果,不能实现滚动内容中的字进行不同颜色的更改,下面实现一个无缝衔接的滚动

C#通过进程调用外部应用的实现示例

《C#通过进程调用外部应用的实现示例》本文主要介绍了C#通过进程调用外部应用的实现示例,以WINFORM应用程序为例,在C#应用程序中调用PYTHON程序,具有一定的参考价值,感兴趣的可以了解一下... 目录窗口程序类进程信息类 系统设置类 以WINFORM应用程序为例,在C#应用程序中调用python程序

利用Python实现可回滚方案的示例代码

《利用Python实现可回滚方案的示例代码》很多项目翻车不是因为不会做,而是走错了方向却没法回头,技术选型失败的风险我们都清楚,但真正能提前规划“回滚方案”的人不多,本文从实际项目出发,教你如何用Py... 目录描述题解答案(核心思路)题解代码分析第一步:抽象缓存接口第二步:实现两个版本第三步:根据 Fea

Go语言使用slices包轻松实现排序功能

《Go语言使用slices包轻松实现排序功能》在Go语言开发中,对数据进行排序是常见的需求,Go1.18版本引入的slices包提供了简洁高效的排序解决方案,支持内置类型和用户自定义类型的排序操作,本... 目录一、内置类型排序:字符串与整数的应用1. 字符串切片排序2. 整数切片排序二、检查切片排序状态:

python利用backoff实现异常自动重试详解

《python利用backoff实现异常自动重试详解》backoff是一个用于实现重试机制的Python库,通过指数退避或其他策略自动重试失败的操作,下面小编就来和大家详细讲讲如何利用backoff实... 目录1. backoff 库简介2. on_exception 装饰器的原理2.1 核心逻辑2.2

Java实现视频格式转换的完整指南

《Java实现视频格式转换的完整指南》在Java中实现视频格式的转换,通常需要借助第三方工具或库,因为视频的编解码操作复杂且性能需求较高,以下是实现视频格式转换的常用方法和步骤,需要的朋友可以参考下... 目录核心思路方法一:通过调用 FFmpeg 命令步骤示例代码说明优点方法二:使用 Jaffree(FF

基于C#实现MQTT通信实战

《基于C#实现MQTT通信实战》MQTT消息队列遥测传输,在物联网领域应用的很广泛,它是基于Publish/Subscribe模式,具有简单易用,支持QoS,传输效率高的特点,下面我们就来看看C#实现... 目录1、连接主机2、订阅消息3、发布消息MQTT(Message Queueing Telemetr

Java实现图片淡入淡出效果

《Java实现图片淡入淡出效果》在现代图形用户界面和游戏开发中,**图片淡入淡出(FadeIn/Out)**是一种常见且实用的视觉过渡效果,它可以用于启动画面、场景切换、轮播图、提示框弹出等场景,通过... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细