今天就是看怎么把论文的python源码预测出来的smpl模型的姿势和形状参数弄到unity版本的smpl里,但是python版本的和unity版本的不一样。

  先看看他的fit_3d.py:



 里面的params参数,也就是输出到.pkl文件的内容,包含四个属性:cam_t、f、pose、betas,分别是相机位置、焦距、姿势和形状参数,前两个暂时先无视,先把后两个比较重要的参数弄好。

  用cpickle(python2)看看这两个参数:

with open(img_path,"r") as readFile:
a=pickle.load(readFile)
with open(out_path, 'w') as outf:
print >> outf,a['cam_t'],
print >> outf,a['f'],
print >> outf,a['pose']
print >> outf,a['betas']


  可以发现pose有72个参数,shape有10个参数,想一下smpl刚好有23个关节点+1([SMPL: A Skinned Multi-Person Linear Model](http://files.is.tue.mpg.de/black/papers/SMPL2015.pdf)里是这么说的,虽然我一直想把它当成24个关节点),并且在unity版本的smpl中的SMPLModifyBones.cs脚本里有这一段代码:
```
_boneNameToJointIndex = new Dictionary();

_boneNameToJointIndex.Add("Pelvis", 0);

_boneNameToJointIndex.Add("L_Hip", 1);

_boneNameToJointIndex.Add("R_Hip", 2);

_boneNameToJointIndex.Add("Spine1", 3);

_boneNameToJointIndex.Add("L_Knee", 4);

_boneNameToJointIndex.Add("R_Knee", 5);

_boneNameToJointIndex.Add("Spine2", 6);

_boneNameToJointIndex.Add("L_Ankle", 7);

_boneNameToJointIndex.Add("R_Ankle", 8);

_boneNameToJointIndex.Add("Spine3", 9);

_boneNameToJointIndex.Add("L_Foot", 10);

_boneNameToJointIndex.Add("R_Foot", 11);

_boneNameToJointIndex.Add("Neck", 12);

_boneNameToJointIndex.Add("L_Collar", 13);

_boneNameToJointIndex.Add("R_Collar", 14);

_boneNameToJointIndex.Add("Head", 15);

_boneNameToJointIndex.Add("L_Shoulder", 16);

_boneNameToJointIndex.Add("R_Shoulder", 17);

_boneNameToJointIndex.Add("L_Elbow", 18);

_boneNameToJointIndex.Add("R_Elbow", 19);

_boneNameToJointIndex.Add("L_Wrist", 20);

_boneNameToJointIndex.Add("R_Wrist", 21);

_boneNameToJointIndex.Add("L_Hand", 22);

_boneNameToJointIndex.Add("R_Hand", 23);

  也就是说姿势中每连续的三个值代表一个结点的旋转角,而这个旋转角是localRotation,相对于它父亲的旋转角,SMPL: A Skinned Multi-Person Linear Model这篇文章里也有提及:
<img src="https://i.loli.net/2019/01/15/5c3d93f1c4aa2.png" alt="3.png" title="3.png" />
&emsp;&emsp;那么只需要按照这个顺序将pose参数导入到unity的smpl模型里就行了吧。我按照SMPLModifyBones.cs的updateBoneAngles函数仿写了以下代码看看效果:

public void SetParam(GameObject model,List poseParam, List shapeParam)//设置pose和shape参数

{

var smr = model.GetComponent();

var _bones = smr.bones;

var _boneNamePrefix = "";

foreach (Transform bone in _bones)
{
if (bone.name.EndsWith("root"))
{
int index = bone.name.IndexOf("root");
_boneNamePrefix = bone.name.Substring(0, index);
break;
}
}
foreach (var bone in _bones)
{
string boneName = bone.name;
boneName = boneName.Replace(_boneNamePrefix, "");
int id;
if (_boneNameToJointIndex.TryGetValue(boneName,out id))
{
bone.transform.localRotation = Quaternion.Euler(new Vector3(poseParam[id * 3], poseParam[id * 3 + 1], poseParam[id * 3 + 2]));
//bone.transform.rotation = Quaternion.Euler(new Vector3(poseParam[id * 3], poseParam[id * 3 + 1], poseParam[id * 3 + 2]));
} }
float _shapeBlendsScale = 5.0f;
for (int i = 0; i < 10; i++)
{
float pos, neg;
float beta = shapeParam[i] / _shapeBlendsScale; if (beta >= 0)
{
pos = beta;
neg = 0.0f;
}
else
{
pos = 0.0f;
neg = -beta;
} smr.SetBlendShapeWeight(i * 2 + 0, pos * 100.0f); // map [0, 1] space to [0, 100]
smr.SetBlendShapeWeight(i * 2 + 1, neg * 100.0f); // map [0, 1] space to [0, 100]
}

}

&emsp;&emsp;对于下面这张图,明显不对:
<img src="https://i.loli.net/2019/01/15/5c3d9552f145e.jpg" alt="4.jpg" title="4.jpg" style="zoom:180%"/>
<img src="https://i.loli.net/2019/01/15/5c3d95531b648.png" alt="5.png" title="5.png" style="zoom:80%"/>
&emsp;&emsp;smpl_python版的生成效果如下,就是个obj文件我直接导入进去了,想获得obj文件就改一下python版的smpl文件夹里的hello_smpl.py中的pose和shape即可。
<img src="https://i.loli.net/2019/01/15/5c3d96a651086.png" alt="6.png" title="6.png" style="zoom:80%"/>
&emsp;&emsp;但是smpl的python代码里或者根据图像生成人物模型的源代码里压根没有类似的关于关节点的定义。
&emsp;&emsp;瞎试了半天,最后发现如果只看脚的话貌似左右脚的姿势刚好反了,于是我就把代码里的L和R互换位置看看:

_boneNameToJointIndex.Add("Pelvis", 0);

_boneNameToJointIndex.Add("R_Hip", 1);

_boneNameToJointIndex.Add("L_Hip", 2);

_boneNameToJointIndex.Add("Spine1", 3);

_boneNameToJointIndex.Add("R_Knee", 4);

_boneNameToJointIndex.Add("L_Knee", 5);

_boneNameToJointIndex.Add("Spine2", 6);

_boneNameToJointIndex.Add("R_Ankle", 7);

_boneNameToJointIndex.Add("L_Ankle", 8);

_boneNameToJointIndex.Add("Spine3", 9);

_boneNameToJointIndex.Add("R_Foot", 10);

_boneNameToJointIndex.Add("L_Foot", 11);

_boneNameToJointIndex.Add("Neck", 12);

_boneNameToJointIndex.Add("R_Collar", 13);

_boneNameToJointIndex.Add("L_Collar", 14);

_boneNameToJointIndex.Add("Head", 15);

_boneNameToJointIndex.Add("R_Shoulder", 16);

_boneNameToJointIndex.Add("L_Shoulder", 17);

_boneNameToJointIndex.Add("R_Elbow", 18);

_boneNameToJointIndex.Add("L_Elbow", 19);

_boneNameToJointIndex.Add("R_Wrist", 20);

_boneNameToJointIndex.Add("L_Wrist", 21);

_boneNameToJointIndex.Add("R_Hand", 22);

_boneNameToJointIndex.Add("L_Hand", 23);

&emsp;&emsp;看上去正常了一点,虽然还有点差距,但是对于用来做初始化而言感觉差不多了,之后就手动调各个关节的旋转角度即可。
<img src="https://i.loli.net/2019/01/15/5c3d976600886.png" alt="7.png" title="7.png" style="zoom:80%"/>
<img src="https://i.loli.net/2019/01/15/5c3d9765f23a2.png" alt="8.png" title="8.png" style="zoom:80%"/>
<img src="https://i.loli.net/2019/01/15/5c3d9875845c7.png" alt="9.png" title="9.png" style="zoom:80%"/>
&emsp;&emsp;然后老师还说把人和物体交互的图像作为背景能更加方便用户标注,于是我查了一下发现可以用这个方法[Unity项目使用静态图片做背景](https://segmentfault.com/a/1190000008505014)。效果如下:
<img src="https://i.loli.net/2019/01/15/5c3da1798b117.png" alt="10.png" title="10.png" style="zoom:80%"/>

3dContactPointAnnotationTool开发日志(三二)的更多相关文章

  1. 3dContactPointAnnotationTool开发日志(二九)

      今天想着在Windows平台上跑通那个代码,不过它的官网上写的支持平台不包括windows,但我还是想试试,因为看他的依赖好像和平台的关系不是特别大.   看了下它的py代码,不知道是py2还是p ...

  2. 3dContactPointAnnotationTool开发日志(二六)

      之前给老师看了看我的毕设,老师觉得操作太复杂了,要能像3ds max里那样可以拖动物体的轴进行平移,沿着显示的圆圈旋转以及缩放啥的.说白了就是在Unity3d的Game视图显示出Scene视图里的 ...

  3. 3dContactPointAnnotationTool开发日志(二五)

    记录一下当前进度:

  4. 3dContactPointAnnotationTool开发日志(二四)

      添加了清空2d接触点的按钮,将输出的2d接触点的单位变成了像素,原点在图像的左下角.   对于obj文件的适配更加多样化了.

  5. 3dContactPointAnnotationTool开发日志(二二)

      昨天是实现了显示GameObject子GameObject的选项卡功能,今天就是要让statusPanel可以控制它们的位置.旋转和缩放了.   没什么难的,对应选项卡绑定上对应的物体或子物体即可 ...

  6. 3dContactPointAnnotationTool开发日志(二一)

      今天完成了修改按钮颜色,添加smpl模型到工具,以及可以显示物体子物体对应选项卡的功能.把之前的meshRenderer+meshFilter都改成了skinnedMeshRenderer,因为s ...

  7. 3dContactPointAnnotationTool开发日志(二十)

      为了使工具更人性化,我又在每个status的text上绑了个可以拖拽实现值改变的脚本,但是不知道为啥rotx那个值越过+-90范围后连续修改就会产生抖动的现象,试了很多方法也没能弄好,不过实际用起 ...

  8. 3dContactPointAnnotationTool开发日志(二)

      今天看的时候发现其实www的方式是可以根据指定路径读取本地图片到Image中的.也就是昨天提到的第二种方式.   随便选了个图片做示范: 修改后的代码如下: using System.Collec ...

  9. 3dContactPointAnnotationTool开发日志(三十)

      在vs2017里生成opencv时遇到了无法打开python27_d.lib的问题,具体解决请看这个,不过我用的是方法2,python37_d.lib找不到同理.   Windows下可以用的op ...

随机推荐

  1. EJS 模板中,js 如何获取后端传来的数据

    在 ejs 模板中,想让 js 的代码获得后端传来的数据,要在<%=%>的外面加一对引号. 如下图,从后端给 chatroom.ejs 传进去一个 avatar 变量,是个字符串类型的. ...

  2. Linux 下 终端 相关的命令

    1. 概述 Linux 服务器, 通常可以由多个终端连接 简单介绍一些 终端 相关的操作 最终的目的, 是定位到某个终端, 然后把它 踢下来, 甚至可以不让他再次连接 2. 环境 操作系统 CentO ...

  3. 如何加入别人的Git项目——Git Fork指南

    如何加入别人的Git项目--Git Fork指南 首先,在网页打开别人Git上的项目,点击右上角的.下图因为Fork过了,所以灰了. 随即弹出如下窗口,当然选择确定. 于是,我们在在自己的项目列表可以 ...

  4. 20155220 2016-2017-2《Java程序设计》课程总结

    20155220 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:师生关系 预备作业2:优秀技能经验 预备作业3:虚拟机linux初接触 第一周学习总结: ...

  5. 20155321 2016-2017-2《Java程序设计》课堂实践项目

    20155321 2016-2017-2<Java程序设计>课堂实践项目 关于String类 split方法 charAt方法 项目题目: 模拟实现Linux下Sort -t : -k 2 ...

  6. 20155322 2017-2018-1《信息安全系统设计》第十周 课下作业-IPC

    20155322 2017-2018-1<信息安全系统设计>课下作业-IPC 作业内容 研究Linux下IPC机制:原理,优缺点,每种机制至少给一个示例,提交研究博客的链接. 共享内存 管 ...

  7. GlusterFS学习之路(三)客户端挂载和管理GlusterFS卷

    一.客户端挂载 可以使用Gluster Native Client方法在GNU / Linux客户端中实现高并发性,性能和透明故障转移.可以使用NFS v3访问gluster卷.已经对GNU / Li ...

  8. Drupal views 学习之初识

    1. 简介 用过Yii框架的同学,应该都会用到过GridView和ListView组件.可以很方便的用网格或列表展示内容. 例如淘宝: 网格显示 列表显示 2. 使用view可以方便的配出类似上面的展 ...

  9. dsp6657的helloworld例程测试-第二篇-CFG文件

    1. 上一篇疑问,int StackTest()这个函数是怎么运行的,后来在.cfg文件找到了答案,.cfg包含丰富的信息,对于用惯C语言的,确实不太习惯 var Memory = xdc.useMo ...

  10. 简单读取 properties文件

    看了网上很多读取的方法,都太过复杂,直接使用下面的方法就可以简单读取 properties文件了 ide使用idea 测试读取成功 import java.util.ResourceBundle; p ...