当前位置:网站首页>ThreeDPoseTracker项目解析
ThreeDPoseTracker项目解析
2022-07-06 01:08:00 【烫青菜】
目录
一、源码
Digital Standard Co., LTD. (github.com)
参考文章:
二、肢体驱动
1.算法模型
(1)数据说明
项目中算法模型预测数据的代码主要为VNectBarracudaRunner.cs。函数PredictPose()中更新的节点数据为JointPoint中的三个变量(也就是驱动时要用到的算法数据):
public class JointPoint
{
public Vector3 Pos3D = new Vector3();
public float score3D;
public bool Visibled;
}JointPoint类中还有几个变量是预测过程中用于数据优化(防抖动等)的:
public class JointPoint
{
public Vector3 Now3D = new Vector3();
public Vector3[] PrevPos3D = new Vector3[6];
public Vector3 P = new Vector3();
public Vector3 X = new Vector3();
public Vector3 K = new Vector3();
}JointPoint类中其他的数据需要在肢体驱动时自己推算:
public class JointPoint
{
public Transform Transform = null;
public Quaternion InitRotation;
public Quaternion Inverse;
public Quaternion InverseRotation;
public JointPoint Child = null;
public JointPoint Parent = null;
}(2)算法理论解析
解决抖动:卡尔曼滤波+低通滤波: 关键点平滑方案
算法模型解析:模型解析 、 heatmap&offset
- 有三个input,其实都是一样,都要输入(448,448,3)的图片:
private void UpdateVNectAsync()
{
input = new Tensor(videoCapture.MainTexture, 3);
if (inputs[inputName_1] == null)
{
inputs[inputName_1] = input;
inputs[inputName_2] = new Tensor(videoCapture.MainTexture, 3);
inputs[inputName_3] = new Tensor(videoCapture.MainTexture, 3);
}
else
{
inputs[inputName_3].Dispose();
inputs[inputName_3] = inputs[inputName_2];
inputs[inputName_2] = inputs[inputName_1];
inputs[inputName_1] = input;
}
if (!Lock && videoCapture.IsPlay())
{
StartCoroutine(ExecuteModelAsync());
}
}
- 四个output,但我们只用后两个:
for (var i = 2; i < _model.outputs.Count; i++)
{
b_outputs[i] = _worker.PeekOutput(_model.outputs[i]);
}
offset3D = b_outputs[2].data.Download(b_outputs[2].shape);
heatMap3D = b_outputs[3].data.Download(b_outputs[3].shape);
用heatmap粗略定位关节位置,然后使用offset在heatmap结果上精确调整关节位置。
heatmap的 ( 672 , 28 , 28 ) 代表 24个关节的28个大小为(28,28)的特征图。而offset比heatmap的特征图多三倍,很明显就是刚才说的精确定位,只不过需要在offset中定位到x,y,z三个坐标,所以就是三倍关系了。
- heatmap的顺序是第1个关节的第1个特征图、第1个关节的第2个特征图、…、第2个关节的第1个特征图、第二个关节的第2个特征图、…、第24个关节的第28个特征图
- offsetmap的顺序是第1个关节的第1个特征图对应的x坐标偏移、第1个关节的第2个特征图对应的x坐标偏移、第1个关节的第3个特征图对应的x坐标偏移、…、第1个关节的第28个特征图对应的x坐标偏移、…、第2个关节的第1个特征图对应的x坐标偏移、…、第24个关节的第28个特征图对应的x坐标偏移、第1个关节的第1个特征图对应的y坐标偏移、第1个关节的第2个特征图对应的y坐标偏移、…、第24个关节的第28个特征图对应的y坐标偏移、第1个关节的第1个特征图对应的z坐标偏移、第1个关节的第2个特征图对应的z坐标偏移、…、第24个关节的第28个特征图对应的z坐标偏移。
2.Unity肢体驱动
项目中肢体驱动的代码主要为VNectModel.cs。
(1)相关知识
- 四元素的逆,⽐如⼀个四元数为(1,1,1,1)它的逆是(-1,-1,-1,1)。
Quaternion Inverse(Quaternion rotation);返回⼀个相反的旋转。
- 注视旋转
public static Quaternion LookRotation(Vector3 forward, [DefaultValue("Vector3.up")] Vector3 upwards);创建一个指定的forward 和upward方向的旋转,返回一个计算的四元数。如果用来确定一个transform:如果向量是正交的, z轴将和forward对齐,y轴将和upward对齐。如果forward方向是0将会报错。
(2)项目中的使用
由当前关节的lookrotation=初始旋转InitRotation×对齐矩阵 及
可得出:
a. Quaternion.Inverse(对齐矩阵)=当前旋转Rotation*Quaternion.Inverse(当前关节的lookrotation)
hip.Inverse = Quaternion.Inverse(Quaternion.LookRotation(forward));
hip.InverseRotation = hip.Inverse * hip.InitRotation;函数Init()中有大量类似的代码,目的是求中间矩阵,根据中间矩阵,我们可以通过算法数据得出当前object的旋转。VNectModel.cs中的hip.InverseRotation就是Quaternion.Inverse(对齐矩阵)。
b. 当前旋转Rotation=当前关节的lookrotation×Quaternion.Inverse(对齐矩阵)
//基于根关节和左右胯关节坐标计算出人体朝向,然后以此作为所有关节LookRotation的y方向
var forward = TriangleNormal(jointPoints[PositionIndex.hip.Int()].Pos3D, jointPoints[PositionIndex.lThighBend.Int()].Pos3D, jointPoints[PositionIndex.rThighBend.Int()].Pos3D);
jointPoints[***].Transform.rotation = Quaternion.LookRotation(Vector3.up, forward) * jointPoint[***].InverseRotation;
函数PoseUpdate()用于肢体驱动,上面这行代码就是用来计算关节的当前旋转的。
c. 对齐矩阵=当前关节的lookrotation*Quaternion.Inverse(当前旋转Rotation);
root = animator.GetBoneTransform(HumanBodyBones.Hips);
midRoot = Quaternion.Inverse(root.rotation) * Quaternion.LookRotation(forward);//midRoot 为对齐矩阵这些代码在项目中不存在,只是为了更好的解释公式。
三、肢体驱动流程图

边栏推荐
- Cloud guide DNS, knowledge popularization and classroom notes
- Four commonly used techniques for anti aliasing
- Redis' cache penetration, cache breakdown, cache avalanche
- Starting from 1.5, build a micro Service Framework - call chain tracking traceid
- Zhuhai's waste gas treatment scheme was exposed
- How spark gets columns in dataframe --column, $, column, apply
- 毕设-基于SSM高校学生社团管理系统
- China Taiwan strategy - Chapter 8: digital marketing assisted by China Taiwan
- IP storage and query in MySQL
- GNSS terminology
猜你喜欢

Fibonacci number

SSH login is stuck and disconnected

Intensive learning weekly, issue 52: depth cuprl, distspectrl & double deep q-network

Spark AQE

VSphere implements virtual machine migration

Cannot resolve symbol error

Dede collection plug-in free collection release push plug-in
![[groovy] JSON serialization (jsonbuilder builder | generates JSON string with root node name | generates JSON string without root node name)](/img/dd/bffe27b04d830d70f30df95a82b3d2.jpg)
[groovy] JSON serialization (jsonbuilder builder | generates JSON string with root node name | generates JSON string without root node name)
![Cf:d. insert a progression [about the insert in the array + the nature of absolute value + greedy top-down]](/img/9e/c933f454a39d906a407e4d415f0b87.png)
Cf:d. insert a progression [about the insert in the array + the nature of absolute value + greedy top-down]

The growth path of test / development programmers, the problem of thinking about the overall situation
随机推荐
Dedecms plug-in free SEO plug-in summary
图解网络:TCP三次握手背后的原理,为啥两次握手不可以?
小程序容器可以发挥的价值
Installation and use of esxi
Recursive method to realize the insertion operation in binary search tree
视频直播源码,实现本地存储搜索历史记录
猿桌派第三季开播在即,打开出海浪潮下的开发者新视野
golang mqtt/stomp/nats/amqp
China Taiwan strategy - Chapter 8: digital marketing assisted by China Taiwan
Daily practice - February 13, 2022
面试必刷算法TOP101之回溯篇 TOP34
DD's command
After 95, the CV engineer posted the payroll and made up this. It's really fragrant
Mysql--- query the top 5 students
servlet(1)
[groovy] XML serialization (use markupbuilder to generate XML data | create sub tags under tag closures | use markupbuilderhelper to add XML comments)
WordPress collection plug-in automatically collects fake original free plug-ins
关于#数据库#的问题:(5)查询库存表中每本书的条码、位置和借阅的读者编号
Use of crawler manual 02 requests
For a deadline, the IT fellow graduated from Tsinghua suddenly died on the toilet