GitHub Project: ThreeDPoseUnityBarracuda
尝试理解一下这个基于Unity的Barracuda库制作的单RGB动捕project的运作原理。简单记录一下。可能会有很多错误,纯属图一乐。
原github地址:https://github.com/digital-standard/ThreeDPoseUnityBarracuda
Video Capture
project基础input是一段MP4视频。(我导入了b站某舞蹈up的舞蹈视频,project表现良好.)
(当然同时支持web cam,不过我没有色相头,就算了叭)
在读入video时,会先把整个video投影在videoScreen上。
之后会生成mainTextureCamera。
再把画面映射到MainTexture和InputTexture上。(需要保证人像完整在inputTexture中)
Video Capture到这里就基本结束了。
Model
project内置两个model可供选用。
(后面就用tait叭…好像更喜欢一些)
Model的初始化首先把自带的animator的Bonetransform都读出来。
接着通过model的positionIndex导出Skeleton。
(绿色线条即为Skeleton)
Model的PoseUpdate等会和Barracuda库一起讲吧。
注:Model使用的是VRM格式的模型,不太了解,不在这里进行特殊介绍。
Barracuda
先抄下定义。
The Barracuda package is a lightweight cross-platform neural network inference library for Unity.
“Barracuda包是一个轻量级的跨平台的Unity神经网络推理库.”(直接翻译hh)
同时使用了 Open Neural Network Exchange (ONNX) 来帮助优化机器学习模型的推理。
ONNX的优点:(引用原文)
“优化用于推理(或模型评分)的机器学习模型非常困难,因为需要调整模型和推理库,充分利用硬件功能。 如果想要在不同类型的平台(云/Edge、CPU/GPU 等)上获得最佳性能,实现起来会异常困难,因为每个平台都有不同的功能和特性。 如果模型来自需要在各种平台上运行的多种框架,会极大增加复杂性。 优化框架和硬件的所有不同组合非常耗时。 这就需要一种解决方案,在首选框架中训练一次后能在云或 Edge 上的任意位置运行。 此时 ONNX 便派上了用场。”
更多关于ONNX可看:https://zhuanlan.zhihu.com/p/41255090
在BarracudaRunner中可以选择Barracuda库中的WorkerFactory的Type(默认 auto)
同时也可以选择Model(可以自己导入)。
Verbose大概是选择导入Model时是否导入细节(大概),反正我电脑开了这个project就跑不了了 :cold_sweat:
Use Low Pass Filter是选择是否使用低通滤波器,建议开启,否则Model在做动作时会有奇怪的抖动(Low Pass Filter可以过滤这些抖动)。
其余的就直接默认就好了。(之后都会一一介绍到)
Initialization
在BarracudaRunner中使用到了2D和3D的HeatMap。
HeatMapCol参数是自己定义的(上图中默认为28)。
初始化HeatMap后,接着会载入导入的ONNX模型,具体函数:
1 | _model = ModelLoader.Load(NNModel, Verbose); |
其中NNmodel为在BarracudaRunner中导入的.onnx文件。
之后再通过Model创建Barracuda库中WorkerFactory类里的IWorker,具体函数:
1 | _worker = WorkerFactory.CreateWorker(WorkerType, _model, Verbose); |
其中_worker为IWorker类型,IWorker作用:
A worker is able to schedule models execution for a given backend
大概就是可以通过我们导入的onnx模型来控制我们的Model。
之后便开始等待视频的载入。
WaitLoad
在waitload时,会先通过设置的InitImg让我们之前初始化的worker运行一次,具体函数:
1 | inputs[inputName_1] = new Tensor(InitImg); |
startManualSchedule函数官方解释:
StartManualSchedule(IDictionary
Non-blocking API that takes mutliple input tensors and schedules network execution one layer at the time. Call MoveNext
on the IEnumerator
obtained from calling this function to schedule next layer of the model.
然后获取worker运行后的offset3D以及heatMap3D的参数。
调用VNectModel的Init函数,初始化Model。
初始化Model完成后,调用PredictPose函数,通过获取到的offset3D和heatMap3D的参数预测Model各个点位的Position。再通过Kalman Filter以及Low Pass Filter对位置的预测进行校准,完成一次PredictPose。(之后再具体介绍PredictPose函数)
等待Model的第一次PredictPose处理完毕后,初始化Video Capture(详见第一节),所有需要的东西就都Load完毕了,接下来就可以愉快地开始跟随视频进行动作捕捉了。
Update
(等待更新……