基于姿态估计的3D动画生成

news2025/1/20 16:23:00

在本文中,我们将尝试通过跟踪 2D 视频中的动作来渲染人物的 3D 动画。

在 3D 图形中制作人物动画需要大量的运动跟踪器来跟踪人物的动作,并且还需要时间手动制作每个肢体的动画。 我们的目标是提供一种节省时间的方法来完成同样的任务。

我们对这个问题的解决方案包括以下步骤:

  • 2D 姿态估计:人体至少需要 17 个标志点才能完整描述其姿态。
  • DeepSORT+FaceReID:跟踪姿势的运动。
  • 将 2D 提升到 3D:我们从上一步获得的坐标是 2D 的。 为了以 3D 方式制作它们的动画,我们需要将这些 2 维坐标映射到 3 维空间。
  • 渲染为 3D:上一步中检测到的这 17 个标志点的坐标现在将是需要动画处理的 3D 角色的四肢关节的位置。

让我们在本文的其余部分详细讨论这些步骤。

NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 

1、2D 姿态估计

如上所述,只需指定 17 个关键点(在深度学习社区中称为landmark points)即可完整描述人体姿势。 你可能已经猜到,我们正在使用深度学习来估计人类的姿势(即跨视频帧跟踪人类的姿势)。 有很多最先进的框架(例如 PoseFlow 和 AlphaPose)可以在github上找到,它们已经实现了相当准确的姿势估计。

第一个框架是由 Yuliang Xiu 等人开发的 PoseFlow。 PoseFlow 算法的基本概述是,该框架首先通过最大化视频所有帧的整体置信度来构建姿势。 下一步是使用称为非极大值抑制(通常缩写为 NMS)的技术删除检测到的冗余姿势。

可以在下面附加的 GIF 中看到,使用 PoseFlow(左侧)估计的姿势在某些帧中存在轻微故障。 这给我们带来了下一个框架:AlphaPose。 AlphaPose由Hao-Shu Fang等人开发。 该框架在帧中检测到的人周围绘制边界框,并估计他们在每个帧中的姿势。 即使一个人被另一个人部分遮挡,它也可以检测姿势。

左:PoseFlow 右:AlphaPose

AlphaPose 框架的代码可以在这里找到。

2、DeepSORT + FaceReID

我们使用 Alpha Pose 来检测视频中人类的姿势。 下一步是跟踪他们的动作,以便能够构建平滑的移动动画。 DeepSORT 框架的研究论文可以在这里找到。

使用 DeepSORT 和 FaceReid 边界框的输出,我们通过以下方式分离不同人的姿势。

在每一帧中绘制人体周围的边界框

检查姿势关键点是否在边界框内的函数

分离不同人的姿势的循环

3、令人振奋的 2D 到 3D

如上所述,我们在姿态估计步骤中获得的坐标是二维的(即它们位于二维空间中)。 但为了实现 3D 动画的主要项目目标,这些坐标必须映射到 3 维空间。 这也是使用......你猜对了!......深度学习! Github 上有一个存储库以及 ICCV ’17 接受的一篇研究论文。 可以在此处找到存储库的链接。

3d-pose-baseline 存储库在 Human3.6M 数据集上训练了他们的模型。 该数据集包含约 360 万人在 17 种不同场景下的 3D 姿势及其相应图像。 简而言之,模型的输入是 360 万人类的图像,所需的输出是数据集中存在的 3D 姿势。 现在,可以构建和调整深度学习模型,直到达到相当的准确度:

4、3D 动画

一旦我们从姿势估计框架中获得了关键点的坐标,就可以将这些坐标提供给 3D 角色身体的每个肢体。 在这里,我们使用Unity作为3D动画环境来完成任务。

每帧的 17 个关键点的坐标存储在一个文本文件中,该文本文件是在 Unity 中使用 C# 读取的。 从文件中读取的坐标现在重新定位到 3D 人形模型中。 这17个关键点与Unity内置的人形头像的身体关键点进行映射。

现在,动画是使用 Unity 的逆运动学(inverse kinematics)、骨骼旋转和四元数完成的。首先看 charanim.cs 的渲染更新函数 update()

void Update()
{
	if (pos == null) {
		return;
	}
	play_time += Time.deltaTime;

	int frame = s_frame + (int)(play_time * 24.057f);  
	if (frame > e_frame) {
		play_time = 0;  
		frame = s_frame;
	}

	if (debug_cube) {
		UpdateCube(frame); 
	}

	Vector3[] now_pos = pos[frame];

	Vector3 pos_forward = TriangleNormal(now_pos[7], now_pos[4], now_pos[1]);
	bone_t[0].position = now_pos[0] * scale_ratio + new Vector3(init_position.x, heal_position, init_position.z);
	bone_t[0].rotation = Quaternion.LookRotation(pos_forward) * init_inv[0] * init_rot[0];

	for (int i = 0; i < bones.Length; i++) {
		int b = bones[i];
		int cb = child_bones[i];
		bone_t[b].rotation = Quaternion.LookRotation(now_pos[b] - now_pos[cb], pos_forward) * init_inv[b] * init_rot[b];
	}

	bone_t[8].rotation = Quaternion.AngleAxis(head_angle, bone_t[11].position - bone_t[14].position) * bone_t[8].rotation;
}

其中的 updateCube() 定义如下:

void UpdateCube(int frame)
	{
		if (cube_t == null) {
			
			cube_t = new Transform[bone_num];

			for (int i = 0; i < bone_num; i++) {
				Transform t = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
				t.transform.parent = this.transform;
				t.localPosition = pos[frame][i] * scale_ratio;
				t.name = i.ToString();
				t.localScale = new Vector3(0.05f, 0.05f, 0.05f);
				cube_t[i] = t;

				Destroy(t.GetComponent<BoxCollider>());
			}
		}
		else {
			
			Vector3 offset = new Vector3(1.2f, 0, 0);

			
			for (int i = 0; i < bone_num; i++) {
				cube_t[i].localPosition = pos[frame][i] * scale_ratio + new Vector3(0, heal_position, 0) + offset;
			}
		}
	}

最终我们得到的结果如下,视频点击这里:

还不错!

5、结束语

总而言之,我们能够实现视频中多个人的姿势估计,并使用 Unity 等 3D 环境制作运动动画,同时还保持视频中两个不同人之间的相对位置。我们项目的 Github 存储库链接可以在这里找到。


原文链接:从姿态估计到3D动画 - BimAnt

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1280198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SmartSoftHelp8,FrameCode极速二次开发框架源码

1.winform outlook style UI C/S 极速开发框架 netframework 2.0 2.winform toolbar style UI C/S 极速开发框架 netframework 2.0 3.WPF toolbar style UI C/S 极速开发框架 netframework 4.0 4.Xadmin-UI jquery B/S 极速开发框架 5.Vue element UI B/S…

ArrayList 与 顺序表 (附洗牌算法)!

曾经我也是一枚学霸&#xff0c;直到有一天想去学渣的世界看看&#xff0c;结果就找不到回去的路了。 目录 1. 线性表 2.顺序表 2.1 接口的实现 3. ArrayList简介 4. ArrayList使用 4.1 ArrayList的构造 4.2 ArrayList常见操作 4.3 ArrayList的遍历 4.4 ArrayList的扩…

永倍达电商模式分析:创新商业模式引领新时代购物潮

在2019年底&#xff0c;全球新冠疫情席卷&#xff0c;导致大量实体经济倒闭&#xff0c;人们纷纷居家躲避&#xff0c;经济陷入下行&#xff0c;企业家面临倒闭威胁。永倍达成立于2020年&#xff0c;是陕西永倍达电子商务有限公司的品牌&#xff0c;而其母公司实际上是天津铸源…

Stable Diffusion 系列教程 - 1 基础准备(针对新手)

使用SD有两种方式&#xff1a; 本地&#xff1a; 显卡要求&#xff1a;硬件环境推荐NVIDIA的具有8G显存的独立显卡&#xff0c;这个显存勉勉强强能摸到门槛。再往下的4G可能面临各种炸显存、炼丹失败、无法生成图片等各种问题。对于8G显存&#xff0c;1.0模型就不行&#xff0…

前端入门(四)Ajax、Promise异步、Axios通信、vue-router路由、组件库

文章目录 AjaxAjax特点 Promise 异步编程&#xff08;缺&#xff09;Promise基本使用状态 - PromiseState结果 - PromiseResult AxiosVue中使用AxiosAxios请求方式getpostput和patchdelete并发请求 Vue路由 - vue-router单页面Web应用&#xff08;single page web application&…

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作

目录 一、成员访问 1、[ ]&at 2、front( )&back( ) 二、插入元素 三、删除元素 四、替换元素 五、查找元素 1、查找第一次出现位置 2 、在指定范围内查找 六、交换字符串 七、c_str 八、rfind&substr 一、成员访问 1、[ ]&at 虽然二者功能一样&…

LeetCode | 101. 对称二叉树

LeetCode | 101. 对称二叉树 OJ链接 在本函数里不好进行判断&#xff0c;我们另外定义一个函数来如果两个都相等为空&#xff0c;就返回true一个为空&#xff0c;一个不为空都不为空,就比较值然后递归1的左&#xff0c;2的右&#xff0c;1的右&#xff0c;2的左 bool _isSymm…

javaee实验:MVC 框架技术应用——URL 映射及方法参数的使用

目录 urlmvc框架mvc框架的设计mvc流程 实验目的实验内容实验过程创建项目创建项目结构编写代码简单测试一下 url 和 Hypertext 以及 HTTP 一样&#xff0c;URL 是 Web 中的一个核心概念。它是浏览器用来检索 web 上公布的任何资源的机制 URL 代表着是统一资源定位符&#xff…

《洛谷深入浅出进阶篇》模意义下的乘法逆元+洛谷P3811

什么是乘法逆元&#xff1f; 算数意义上的乘法逆元指的是倒数&#xff0c;即&#xff1a;a*&#xff08;1/a&#xff09;1 所以 1/a 是 a在算数意义下的乘法逆元&#xff0c;或者可以说二者互为逆元。 这有什么用呢&#xff1f; 除以a就等于乘上a的乘法逆元&#xff0c;乘以…

keil5 --工程创建

一&#xff0c;文件夹介绍 首先去官网过去其他地方获取到官方提供的标准库文件 下面这个我是在官网进行下载的 我们在打开keil的时候会弹出一个在线下载的框&#xff08;这个框这里先不做说明&#xff0c;后面在继续讲解&#xff09;&#xff0c;我们不使用这个在线下载功能&a…

LangChain 19 Agents Reason+Action自定义agent处理OpenAI的计算缺陷

LangChain系列文章 LangChain 实现给动物取名字&#xff0c;LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字LangChain 3使用Agent访问Wikipedia和llm-math计算狗的平均年龄LangChain 4用向量数据库Faiss存储&#xff0c;读取YouTube的视频文本搜索I…

配置SAP用户密码策略(不用重启服务器的方法)

最近公司审计&#xff0c;给我们提出了要优化密码策略的建议&#xff0c;原因是我们的密码策略太简单了。我稍稍研究了一下。之前是通过RZ10来配置&#xff0c;但是这种方法需要重启服务器&#xff0c;这就比较麻烦。其实有一种方法是通过配置密码策略&#xff0c;不要要重启的…

包装材料ERP是什么?包装材料ERP有什么用

市面上的包装材料种类多种多样&#xff0c;而这些差异化的包装材料对应的产成品规格、型号、质量、销售策略和生产工艺等方面存在诸多差异。 另外&#xff0c;通常包装材料企业的营销渠道比较广泛&#xff0c;不同的销售平台有多样化的业务流程和管理方式&#xff0c;相同的商…

8-2比较三个字符串大小(指针)

#include<stdio.h> #include<string.h>int main(){char str1[20], str2[20], str3[59];//相当于 int a,b,c;printf("please input three str:\n");gets(str1);//sacnf("%s",str1);这里str1是数组名&#xff0c;表示数组空间的起始地址&#xf…

qt 动态生成柱状图

cpp文件 #include "mform.h" #include "ui_mform.h" #include <QBarSeries> #include <QBarSet> #include <QtCharts> #include <QPushButton> #include <QtCharts/QChartView> #include <QtCharts/QPieSeries> #inc…

图解系列--功能追加协议,构建Web内容

功能追加协议 1.消除 HTTP 瓶颈的 SPDY 1.1.HTTP 的瓶颈 使用 HTTP 协议探知服务器上是否有内容更新&#xff0c;就必须频繁地从客户端到服务器端进行确认。如果服务器上没有内容更新&#xff0c;那么就会产生徒劳的通信。 若想在现有 Web 实现所需的功能&#xff0c;以下这些…

LLM | 一文搞懂Langchain的概念,相关组件,以及大模型微调~

本文主要介绍了 Langchain的概念&#xff0c;相关组件&#xff0c;以及大模型微调代码实现~ 1.什么是LangChain&#xff1f; LangChain是一个平台&#xff0c;提供工具和API&#xff0c;用于构建由语言模型&#xff08;LLM&#xff09;驱动的应用程序。它简化了 LLM 与项目的集…

自动驾驶学习笔记(十三)——感知基础

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo Beta宣讲和线下沙龙》免费报名—>传送门 文章目录 前言 传感器 测距原理 坐标系 标定 同…

一个用c#瞎写的sftp工具

0.下载地址 https://wwus.lanzouj.com/iOZUv1gkgpze 密码:123456 1.能进行单个和批量下载, 没有弄上传 2.速度奇差,可能是某些地方没弄好.有一定的进度显示,但是不太准. 3.很多地方没弄好,有能力的自己弄一下 4.在app.config文件配置sftp

大小堆的实现(C语言)

目录 前言 一种完全二叉树&#xff1a;堆 堆的概念 堆的性质 建堆的时间复杂度 建堆的空间复杂度&#xff1a; 小堆的实现 必要补充 堆的初始化 堆的销毁 向上调整算法 堆的插入 向下调整算法 堆的删除 获取堆顶元素 获取堆中元素个数 堆的判空 最终代码 He…