VIBE:3D人体姿态预测项目复现笔记

2023-05-16

VIBE是一个的3D人体姿态预测开源项目,需要基于该项目作一些开发,首先需要能够搭建和是的环境成功复现它。

不过,这个项目的复现的,真的不是一星半点的艰难。

1、系统选择

之前一直用的Windows,最开始想在windows上复现它,经过一周的折腾,我放弃了。

接着尝试了Docker,由于GPU的问题放弃了。

接着尝试了WSL,虽然基本解决了GPU加速问题,但其中的某些方法还是只能使用CPU,导致速度异常慢,在最后的渲染阶段也是不能正常渲染的,最终也放弃了。

一不做二不休,把自己的电脑整个重装系统,变成一台Ubuntu电脑。

所以,如果你也想验证该项目,那么就不要在Windows上纠缠了,也不要去考虑虚拟机什么的,直接换系统吧。

2、硬件

官方是在2080Ti显卡上测试,宣称可达到30FPS,所以这个玩意是真的吃性能的,1060会报显存不够的错误的。

本人做测试时,电脑信息如下

3、准备阶段

  • 显卡驱动、在ubuntu上安装Nvidia的驱动,简直是一件%#@%@¥%¥#%,为此重装了三遍系统。。。
  • 安装Anaconda、VSCode(在ubuntu上不推荐pycharm,pycharm的坑有点多)、以及科学上网工具(如果有能力)

4、克隆项目

git clone https://github.com/mkocabas/VIBE.git

5、开始安装

官方提供了两种安装方式,pip和conda,因为其安装过程是需要创建虚拟环境的,个人习惯使用conda,

所以使用conda的安装:

cd VIBE
# pip
# source scripts/install_pip.sh
# conda
source scripts/install_conda.sh

打住!还是打开该文件,对照着内容一步一步手动来吧

首先创建 名为 vibe-env python=3.7的虚拟环境,接着激活该环境

接着手动使用pip安装numpy==1.17.5 torch==1.4.0 torchvision==0.5.0,(为了避免后面其他坑,这里就按照指定版本安装)

如果torch和torchvision提示找不到对应的版本,可以去pip官方源下载对应的whl文件后手动安装

“pip install git+https:……pytube.git --upgrade”是安装一个下载youtobe视频的开源项目,这个可以跳过。

其次如果需要安装,查看pytube项目主页,可以直接使用“pip install pytube”来安装。

最后就是根据“requirement.txt”来安装依赖项。

pip install -r requirements.txt

(本人在上面这一步折腾了很久,,,有很多坑的,但是由于其中一些项目的更新,已经VIBE项目作者在19天前也对该文件做了更新,目前亲测可以一次成功)

如果不成功,按照文件内所列依赖项逐个手动安装,并逐一解决问题即可。

6、测试

模型与示例视频准备:

source scripts/prepare_data.sh

当然参考该文件内容,要下在vibe_data.zip文件,我上传到了csdn,可以手动下载:https://download.csdn.net/download/Raink_LH/12692105

其他步骤参可照上图中的注释进行操作即可。

最后运行demo.py文件

编译器运行需要配置一定的参数,参照官方示例:

# Run on a local video
python demo.py --vid_file sample_video.mp4 --output_folder output/ --display

7、效果

我下载了B站上的舞蹈视频来作测试

该Demo中对3D-pose的预测分三个步骤:

  1. 首先是使用了ffmpeg将视频解析成一帧一帧的图片,在对每张图片使用Yolo进行人物检测,记录检测到人物及区域(框)的信息。
  2. 按照检测结果进行裁减图像,喂入VIBE pose检测模型进行检测,并记录每一帧所对应的结果(包括预测的虚拟相机位置、关节点、人物三角网格数据等)。
  3. 针对每一帧的预测结果,使用pyrender进行渲染,并将渲染结果合并成一个视频。

对与第一个阶段,GPU基本在70%左右,CPU在60%左右,第二阶段CPU和GPU都在很低和100%直接波动,应该是逐帧检测时,每一帧都比较消耗资源的。第三阶段渲染时,GPU使用一般,但CPU持续在95%以上。

我使用的视频是720P的,人物检测才40FPS,3D-pose检测在25FPS

运行输出如下

输出的结果视频,截取了一点,下过如下

总体来说,效果可以,人物在侧向、多人物重叠时效果不佳。

8、补充说明

vibe模型是基于pytorch的,输出的数据包含多个类别。3D-pose结果使用了smplx

结果展示使用的是pyrender,

上文中展示的是使用了输出结果中的三角人物网格数据(verts)。

更为简单直观的可以使用关节点数据(kp_3d),是归一化后的三位坐标,每个人物包含49个关节坐标。


2021年5月26日补充

因为很久没有用到这个项目了,很多地方都记不清了。之前一次补充,提到了三为节点渲染,但是很多人反馈“joints3d”关键字错误。

想来想去,终于想起来了,实在抱歉,之前忘了一点东西

(源码中是针对每一帧图像预测,在对比前后帧,做人物追踪,然后再把每一帧预测的数据转换成正对每一帧中不同人的数据,在做这个数据整理的过程中,原项目只整理了需要用到的两组数据,其他直接抛弃了,所以后面渲染三维节点或者用其他数据时就会报错)

如果还有哪里有遗漏的,欢迎补充!

因此对下文做了一些修改:

8.1关于三维关节点

在官方demo.py中,有关于输出结果的一个字典:

output_dict = {
                'pred_cam': pred_cam,
                'orig_cam': orig_cam,
                'verts': pred_verts,
                'pose': pred_pose,
                'betas': pred_betas,
                'joints3d': pred_joints3d,
                'joints2d': joints2d,
                'bboxes': bboxes,
                'frame_ids': frames,
               }

同时在其下文,能找到如下的代码:

# prepare results for rendering
frame_results = prepare_rendering_results(vibe_results, num_frames)

吧vibe_result,转换成frame_results,找到这个方法的定义prepare_rendering_results(),

可以看到原项目中只把verts和cam转换过来了,其他的没用到。

所以需要手动增加之后要用的数据,比如joints3d。

def prepare_rendering_results(vibe_results, nframes):
    frame_results = [{} for _ in range(nframes)]
    for person_id, person_data in vibe_results.items():
        for idx, frame_id in enumerate(person_data['frame_ids']):
            frame_results[frame_id][person_id] = {
                'verts': person_data['verts'][idx],
                'cam': person_data['orig_cam'][idx],
                'joints3d': person_data['joints3d'][idx],  # ---需要把每一帧预测出的结果加入到针对每个人的结果中!需要什么加什么!
            }

 

8.2关于关节点渲染图

官方使用pyrender渲染人物,使用的是'verts': pred_verts。

主要代码在demo.py的结尾处:

for frame_idx in tqdm(range(len(image_file_names))):
        img_fname = image_file_names[frame_idx]
        img = cv2.imread(img_fname)
        # …… # 个人省略了一些代码
        for person_id, person_data in frame_results[frame_idx].items():
            # 这里 拿到每个人的verts,camera参数,以及每个人的颜色
            frame_verts = person_data['verts']
            frame_cam = person_data['cam']
            mc = mesh_color[person_id]
            mesh_filename = None
            # …… # 个人省略了一些代码
            # 这里就是基于结果对每一帧图像进行渲染的
            img = renderer.render(
                img,
                frame_verts,
                cam=frame_cam,
                color=mc,
                mesh_filename=mesh_filename,
            )            
            # …… # 个人省略了一些代码

那么如果需要3D的关节点渲染效果,就需要传入3D节点数据,并重写渲染方法。

首先对上面做小小修改:

for frame_idx in tqdm(range(len(image_file_names))):
    img_fname = image_file_names[frame_idx]
    img = cv2.imread(img_fname)
    # …… # 个人省略了一些代码
    for person_id, person_data in frame_results[frame_idx].items():
        # 这里拿到3维关节点数据
        frame_joints3d = person_data['joints3d']
        frame_cam = person_data['cam']
        mesh_filename = None
        # …… # 个人省略了一些代码
        # 重写一个渲染方法,传入3D的关节点数据
        img = renderer.render_s(
                                img,
                                frame_joints3d,
                                cam=frame_cam,
                                mesh_filename=mesh_filename,
                                )
        # …… # 个人省略了一些代码

接着在render.py中,仿照原有的,实现一个render_s()方法

def render_s(self, img, joints, cam, angle=None, axis=None, mesh_filename=None):    
    tfs = np.tile(np.eye(4), (len(joints), 1, 1))
    tfs[:, :3, 3] = joints
    sx, sy, tx, ty = cam

    camera = WeakPerspectiveCamera(
        scale=[sx, -sy],
        translation=[tx, -ty],
        zfar=1000.
    )
    # 点的半径和颜色
    sm = trimesh.creation.uv_sphere(radius=0.02)
    sm.visual.vertex_colors = [0.2, 0.9, 0.2, 1.0]
    mesh = pyrender.Mesh.from_trimesh(sm, poses=tfs)

    mesh_node = self.scene.add(mesh, 'mesh')

    camera_pose = np.eye(4)
    cam_node = self.scene.add(camera, pose=camera_pose)

    if self.wireframe:
        render_flags = RenderFlags.RGBA | RenderFlags.ALL_WIREFRAME
    else:
        render_flags = RenderFlags.RGBA

    rgb, _ = self.renderer.render(self.scene, flags=render_flags)
    valid_mask = (rgb[:, :, -1] > 0)[:, :, np.newaxis]
    output_img = rgb[:, :, :-1] * valid_mask + (1 - valid_mask) * img
    image = output_img.astype(np.uint8)

    self.scene.remove_node(mesh_node)
    self.scene.remove_node(cam_node)

    return image

以上,只是我当时测试的时候临时写的,没有研究过pyrender,参照这官方教程算是勉强能跑,颜色写死的,有需要的可以自己研究对这个方法进行优化。

8.2 关于二维关节点

二维的关节点数据其实在预测接结果中也是有的,

参考8.1中提到的output_dict,其中有:'joints2d': joints2d,以及'bboxes': bboxes两个项,一个是2维关节点数据,一个是检测到人的框的数据。

这两个数据有个特点,都是基于框的中心点的,框的四个数据中,前两个是框中心点,后两个是宽高,关节点坐标貌似也是基于中心点的相对坐标

将二维关节点数据,翻译成图像中绝对坐标:

def get_js2d(image, vibe_results):
    persons = [] # 当前帧中的所有检测到人的结果
    i = 0 # 当前帧中检测到几个人,和这个人的person_id是两回事
    for person_id, pose_data in vibe_results.items():
        pose = {}    
        pose["person_id"] = person_id
        pose["j2ds"] = []          
        joints_2d = pose_data['joints2d'][i]
        bbox = pose_data['bboxes'][i]
        # ---------记录一些常用关节序号
        # 2、3、4是右胳膊, 5、6、7是左胳膊
        # 9-右髋关节, 10-右膝盖, 11-右脚, 12-左髋关节, 13-左膝盖, 14-左脚
        # 37-头顶, 38-脖子
        # 39-肚脐(12), 40-脖下(13), 41-胸前(14)
        # -------------------------------------------------------
        # 可以过滤一些只保留需要的关节点
        #joints_2d = np.vstack((joints_2d[2:5, :], joints_2d[5:8, :], joints_2d[9:12, :], joints_2d[12:15, :], joints_2d[39:42, :]))   
        # 
        for j2d in joints_2d:
            pt = (int(bbox[0] + j2d[0] * (bbox[2] / 2.0)), int(bbox[1] + j2d[1] * (bbox[3] / 2.0)))
            pose["j2ds"].append(pt)
        persons.append(pose)
        i += 1
    return persons

以上,如有错误和建议,还请告诉我

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VIBE:3D人体姿态预测项目复现笔记 的相关文章

  • ubuntu 16.04无法locate boot-repair的解决方法

    ubuntu16 04 07加windows10后无法启动ubunu的问题解决boot repair的安装方法同样适用于ubuntu18 04 ubuntu20 01等系统不能启动的问题 对boot repair修复的原理进行分析 文章目录
  • 论文降低word大小——图像免费压缩方法

    在期刊和毕业论文提交盲审过程中 xff0c 时常对word和pdf的大小进行限制 xff0c 但是在多图的论文中 xff0c 将大小限制在20MB以内较为困难 梳理以下两种方法 xff1a 1 visio图片大小压缩 visio图片插入到w
  • C/C++获取路径下所有文件及其子目录的文件名

    一 功能描述 需要提取某个文件夹下所有文件名字 xff0c 当包含子目录时 xff0c 将子目录及其路径获取到 二 实现方式 使用C语言的opendir函数 DIR span class token operator span dp spa
  • C/C++删除目录文件夹下所有文件(递归)

    一 问题 想要删除目录文件夹 xff0c 类似于rm r的操作 方式1 xff1a 可以使用system直接执行rm r的指令 xff0c system 34 rm r 34 方式2 xff1a 通过C语言内置的函数remove和rmdir
  • Git GUI 的使用

    权限校验 首先 xff0c 服务器需要身份识别 一段RSA加密字符串 启动GUI xff0c 菜单 帮助 Step1 创建密钥 Generate SSH KEY Step2 添加密钥 去你的代码托管服务器 xff0c 你的账号设置中 xff
  • 推荐系统遇上深度学习(九)--评价指标AUC原理及实践

    欢迎关注天善智能 xff0c 我们是专注于商业智能BI xff0c 人工智能AI xff0c 大数据分析与挖掘领域的垂直社区 xff0c 学习 xff0c 问答 求职一站式搞定 xff01 对商业智能BI 大数据分析挖掘 机器学习 xff0
  • VR版“半条命”大火,VR游戏迎来消费级市场的春天?

    彼之砒霜 xff0c 汝之蜜糖 2020年的艰难开局 xff0c 在让众多行业陷入困顿之际 xff0c 却让游戏业迎来了一场流量的盛宴 除了日进斗金的王者 吃鸡 xff0c 还有火爆朋友圈的动森 xff0c 一款3A级VR游戏 Half L
  • 读懂海尔智家大脑:深度体验的本质是深度生活

    了解科技行业的读者 xff0c 应该都对 大脑 这个名词不陌生 黑灯工厂 里指挥生产的 工业大脑 xff0c 繁忙机场里运筹帷幄的 航空大脑 xff0c 还有智慧城市建设的灵魂 城市大脑 如果家也有一颗总揽全局的大脑 xff0c 生活会发生
  • FreeRTOS内核实现05:支持多优先级

    目录 1 支持多优先级的方法 1 1 任务优先级 1 2 基于优先级的就绪列表 1 3 实现基于优先级的调度 2 查找最高优先级就绪任务的方法 2 1 通用方法 2 2 体系结构优化方法 3 修改代码支持多优先级 3 1 创建任务相关 3
  • 无人机和激光雷达,会是一对好cp吗?

    占据一辆无人驾驶汽车成本40 的激光雷达 xff0c 以精准和无死角的空间探测能力 xff0c 成为是无人驾驶领域不可或缺的存在 但和汽车相比 xff0c 似乎激光雷达在无人机上更有用武之地 xff1a 成像精度要求不高 行动自由范围大 成
  • Html文件读取与爬取(个人笔记篇)

    Html文件读取与爬取 xff08 个人笔记篇 xff09 文章目录 Html文件读取与爬取 xff08 个人笔记篇 xff09 html文件读取解析html数据存储爬取到的数据完整代码展示 html文件读取 1 通过open xff1a
  • ubuntu 安装包报:下列软件包有未满足的依赖关系:

    root 64 ubuntu usr src linux 5 0 1 apt install zlib1g dev 正在读取软件包列表 完成 正在分析软件包的依赖关系树 正在读取状态信息 完成 有一些软件包无法被安装 如果您用的是 unst
  • SLAM学习笔记(三) 后端优化与回环检测

    后端优化是对相机位姿和点位置的再度优化 xff08 相较于前端优化规模更大 xff09 xff0c 回环检测是对地图进行的一种修正 xff08 当机器人回到原来位置时 xff0c 地图也实现一个闭环 xff09 后端优化与回环检测 后端优化

随机推荐

  • 基于STM32 HAL库的自定义USB HID设备通信

    最近有个项目需要用到STM32的高速通信 xff0c 准备调试一下STM32的USB功能 xff0c 但是发现F103C8T6只有全速USB xff0c 因此作为HID设备一帧只能发送64字节 xff0c 最小间隔是1ms xff0c 显然
  • PX4-Autopilot安装

    Ubuntu 18 04 43 ROS Melodic 1 PX4源码下载 1 先mkdir一个文件夹 xff0c 在该文件夹下进行源码下载 xff08 因为在github下载很慢 xff0c 所以后续到PX4 Autopilot目录下再单
  • MAVROS(1)offboard模式(手动和roslaunch启动)

    官方教程 xff1a https docs px4 io master en ros mavros offboard html 1 编写功能包 参考 xff1a https blog csdn net weixin 44917390 art
  • VINS-Fusion安装

    1 安装Ceres Solver 官方教程 xff1a http ceres solver org installation html 参考教程 xff1a https blog csdn net qq 27251141 article d
  • APM-MAVROS连接

    1 运行mavros roslaunch mavros apm launch fcu url 61 34 dev ttyUSB0 921600 34 2 读取topic之前先运行以下命令 xff0c 修改飞控广播频率 rosservice
  • PX4 Avoidance(3DVFH*)

    Github地址 xff1a https github com PX4 PX4 Avoidance readme PX4用户指南 xff1a computer vision obstacle avoidance PX4 Avoidance下
  • FreeRTOS源码分析与应用开发04:消息队列

    目录 1 队列结构 2 创建队列 2 1 动态创建队列 2 1 1 xQueueCreate函数 2 1 2 xQueueGenericCreate函数 2 1 3 xQueueGenericReset函数 2 2 静态创建队列 2 2 1
  • APM-SITL Gazebo MAVROS 仿真

    1 配置APM SITL环境 1 下载安装Ardupilot 参考链接 xff1a 官方教程 注意 xff1a 文件install prereqs ubuntu sh路径在 ardupilot Tools environment insta
  • Ego-planner-swarm安装及报错解决

    项目地址 xff1a https github com ZJU FAST Lab ego planner swarmhttps github com ZJU FAST Lab ego planner swarm https github c
  • 单片机和嵌入式系统的区别

    单片机和嵌入式系统的区别 嵌入式和单片机并不是一对相对的概念 xff0c 嵌入式系统包括硬件和软件部分 xff0c 而单片机是单片微型计算机 Single Chip Microcomputer 的简称 xff0c 即微控制单元 Microc
  • 程序员的5个级别,你属于哪一个等级?

    码农和程序员虽说是调侃 xff0c 但是实质上还真的是不一样 还别说 xff0c 程序员还是有分等级的 比如有技术专家 xff0c 初级专员等 程序员的级别不同 xff0c 薪水也是有着天壤之别 免费领取Python学习资料可以加小编的微信
  • FutureTask的使用示例

    今天看书 xff0c 有关于 FutureTask 的介绍 xff0c 感觉还蛮有意思的 xff0c 可以用它来做一些比较花时间的事情 下面打个通俗的比方来说明一下它的用处 xff1a 比如 xff0c 早上一大早的去公交站台等公交 xff
  • 用脚本创建快捷方式

    64 echo off set shortCutPath 61 C Documents and Settings administrator 桌面 set shortCutName 61 报表 set StartPath 61 起始位置 s
  • activemq配置wss协议

    wss是加密协议 xff0c 必须配置https证书 span class token operator lt span sslContext span class token operator gt span span class tok
  • MATLAB 初学者 课堂笔记

    1 预定义变量 xff1a pi i j inf xff1a 无穷大 eps a xff1a a 与大于 a 的最小的浮点数之间的距离 xff0c 距离越小表示精度越高 默认a 61 1 2 矩阵运算 xff1a 左除 C 61 A B 6
  • 备赛笔记:Opencv学习:颜色识别

    OpenCV颜色识别一般要以下步骤 xff1a 1 颜色空间转换 xff0c 将BGR转换为HSV xff0c 用色调区分颜色 2 按照阈值滤出所识别的颜色 3 消除噪点 xff0c 平滑边界 3 提取连续域 xff0c 提取要识别的颜色
  • 树莓派buster安装ROS完整记录

    我敢说这一教程全网找不到相同的 我今天在安装ROS时查了各方教程 xff1a 官方Wiki xff0c Google xff0c CSDN都各查了不下10篇 xff0c 终于综合各教程内容花了大半天下好了 使用硬件及软件 xff1a 树莓派
  • Linux操作系统原理与应用06:系统调用

    目录 1 Linux中的各种接口 1 1 LSB标准 1 2 Linux API 1 2 1 概述 1 2 2 Linux内核系统调用接口 1 2 3 C标准库 1 3 Linux ABI 1 4 内核API 1 5 系统调用与各种接口的关
  • 将csdn博客转换成makedown形式的文件并保存

    span class token comment 作者 Rain span span class token keyword import span re span class token keyword import span parse
  • VIBE:3D人体姿态预测项目复现笔记

    VIBE是一个的3D人体姿态预测开源项目 xff0c 需要基于该项目作一些开发 xff0c 首先需要能够搭建和是的环境成功复现它 不过 xff0c 这个项目的复现的 xff0c 真的不是一星半点的艰难 1 系统选择 之前一直用的Window