ThreeDPoseTracker中3D点的预测

    private IEnumerator ExecuteModelAsync()
    {
        if(Lock)
        {
            yield return null;
        }

        // Create input and Execute model
        yield return _worker.StartManualSchedule(inputs);

        if (!Lock)
        {
            // Get outputs
            for (var i = 2; i < _model.outputs.Count; i++)
            {
                b_outputs[i] = _worker.PeekOutput(_model.outputs[i]);
            }

            // Get data from outputs
            //heatMap2D = b_outputs[0].data.Download(b_outputs[0].shape);
            //offset2D = b_outputs[1].data.Download(b_outputs[1].shape);
            offset3D = b_outputs[2].data.Download(b_outputs[2].shape);
            heatMap3D = b_outputs[3].data.Download(b_outputs[3].shape);

            PredictPose();

            fpsCounter++;
        }
    }

  

在Update()循环中调用:

UpdateVNectModel();

而UpdateVNectModel = new UpdateVNectModelDelegate(UpdateVNectAsync); 委托调用UpdateVNectAsync

UpdateVNectAsync 中开启了协程ExecuteModelAsync,

这个协程它使用了yield return语句来返回一个IEnumerable类型的结果。yield return语句并不会终止方法的执行,而是暂停方法的执行,并返回当前的值给调用者。当调用者再次请求下一个值时,方法会从上次暂停的地方继续执行,直到遇到下一个yield return语句或者方法的结尾。

_worker.StartManualSchedule(inputs)做的是模型的推理,inputs就是一组视频图片

ThreeDPoseTracker中3D点的预测_第1张图片

 _worker.StartManualSchedule,完成之后,输出会存放的_worker里面,通过调用_worker.PeekOutput取出output放到b_outputs里面

ThreeDPoseTracker中3D点的预测_第2张图片

 根据每个输出的形状(shape),将其数据下载到对应的float数组中(offset3D和heatMap3D)。

调用PredictPose方法,根据offset3D和heatMap3D数组中的值计算出每个关节点的三维坐标,并存储到jointPoints数组中。

最后,将fpsCounter变量加一,表示模型执行了一次。这个变量可以用于统计模型的执行频率。

------------------------------------------------------------------------------------------------------------------------------

PredictPose这个方法的作用是根据模型输出的三维偏移量和热图,预测人体的三维姿态,并对每个关节点的位置进行滤波和平滑。具体来说,它做了以下几个步骤:

  • 首先,定义了一些变量,如score, filterWindow, cubeOffsetSquared等,用于后续的计算。
  • 然后,使用一个循环,遍历每个关节点(JointNum = 19),并找出每个关节点在三维热图中的最大概率位置(maxXIndex, maxYIndex, maxZIndex)。然后根据三维偏移量数组(offset3D)和热图的尺寸(HeatMapCol = 32),计算出每个关节点在三维空间中的坐标(jp.Now3D.x, jp.Now3D.y, jp.Now3D.z),并将其添加到滤波器(filter)中。同时,累加每个关节点的概率值(jp.Score3D),并用于计算平均分数(EstimatedScore)。
  • 接着,根据一些已知的关节点位置,计算出一些未知的关节点位置,如hip, neck, head和spine。这里使用了一些简单的几何方法,如取两点的中点或者计算三角形的法向量(TriangleNormal)。
  • 最后,使用卡尔曼滤波器(KalmanUpdate)和低通滤波器(NOrderLPF)对每个关节点的位置进行滤波和平滑,并更新每个关节点的可见性(jp.Visibled)。然后根据人体的朝向角度(frwdAngle),判断是否需要更新人体姿态模型(VNectModel.IsPoseUpdate),并设置相应的阈值(ForwardThreshold和BackwardThreshold)。

 

你可能感兴趣的:(3D,从0开始学3D游戏开发,3d)