卡通驱动项目ThreeDPoseTracker——关键点平滑方案解析

Posted 风翼冰舟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了卡通驱动项目ThreeDPoseTracker——关键点平滑方案解析相关的知识,希望对你有一定的参考价值。

前言

之前对ThreeDPoseTracker深度学习模型unity中的驱动方法进行过解析,还有一个比较重要的就是从深度学习模型出来的3D关键点数据会有抖动,在ThreeDPoseTracker源码中有做两次平滑,一部分是卡尔曼滤波,还有一部分是低通滤波。这次就是对这部分类型进行解析。

国际惯例参考博客:

ThreeDPoseTracker源码VNectBarracudaRunner.cs

理论与代码复现

在源工程的VNectBarracudaRunner.cs脚本中,有一个函数KalmanUpdate便是用于卡尔曼滤波的,而后续有这样一行代码:

jp.PrevPos3D[i] = jp.PrevPos3D[i] * Smooth + jp.PrevPos3D[i - 1] * (1f - Smooth);

便是低通滤波器。

卡尔曼滤波

其实这部分和我在网上搜到的卡尔曼滤波的方法公式很不相同,不过我们还是按照源码来实现解析吧,因为卡尔曼滤波的真正理论貌似有点复杂,暂时不准备去看。

在源码中,预定义了两个参数:KalmanParamQKalmanParamR,为了简写公式就简记为QR,随后按照时间推移不断迭代求解两个数组KP,公式如下:
K = P + Q P + Q + R P = R × P + Q P + R + Q \\beginaligned K &= \\fracP+QP + Q + R\\\\ P &= R \\times\\fracP+QP+R+Q \\endaligned KP=P+Q+RP+Q=R×P+R+QP+Q
随后使用K对关键点进行平滑,首先得有一个中间变量X,设未平滑的姿态为C,则平滑后的姿态D:
D = X + ( C − X ) ∗ K X = D \\beginaligned D&=X+(C-X)*K \\\\ X&=D \\endaligned DX=X+(CX)K=D
这就没了,感觉跟网上的卡尔曼滤波理论完全不同,如果有哪位大佬知道这个究竟属于什么算法,可以在评论区告知或者微信公众号私信讨论,谢谢。

低通滤波

这个和图像里面的低通滤波差不多,不过是一维的,公式很简单
n o w = p r e v ∗ s m o o t h + n o w ∗ ( 1 − s m o o t h ) now = prev*smooth + now *(1-smooth) now=prevsmooth+now(1smooth)
简单的写法是上面,论文用了一个时间轴,将历史的6帧数据联合起来为当前帧平滑,代码如下

jp.PrevPos3D[0] = jp.Pos3D;
for (var i = 1; i < NOrderLPF; i++)

    jp.PrevPos3D[i] = jp.PrevPos3D[i] * Smooth + jp.PrevPos3D[i - 1] * (1f - Smooth);

jp.Pos3D = jp.PrevPos3D[NOrderLPF - 1];

历史第0帧为当前未平滑的帧数据,然后依次向前平滑到帧窗口的最后一帧,那么当前帧平滑后的数据就是窗口的最后一帧。

实验

原始、unity平滑结果、python卡尔曼滤波、python卡尔曼+低通滤波三种方法平滑后的脚部z轴方向的坐标变化如下:

很清晰发现原始数据有很多小棱角的噪声,而经过kalman滤波以后,基本去掉了大部分棱角,然后用低通滤波降低了运动幅度。最终结果与unity源码结果相同,说明复现成功。

我们来看看动作的可视化效果:

未经平滑的可视化

经过卡尔曼和低通平滑后:

结论

论文的平滑方法虽然很少代码就搞定,但是从效果图可以发现,平滑效果还是不错的。

完整的python实现放在微信公众号的简介中描述的github中,有兴趣可以去找找。或者在公众号回复“ThreeDPose",同时文章也同步到微信公众号中,有疑问或者兴趣欢迎公众号私信。

以上是关于卡通驱动项目ThreeDPoseTracker——关键点平滑方案解析的主要内容,如果未能解决你的问题,请参考以下文章

卡通驱动项目ThreeDPoseTracker——关键点平滑方案解析

卡通驱动项目ThreeDPoseTracker——关键点平滑方案解析

卡通角色表情驱动系列一

卡通角色表情驱动系列一

卡通角色表情驱动系列二

卡通角色表情驱动系列二