使用unity3d和tensorflow实现基于姿态估计的体感游戏

前言

之前做姿态识别,梦想着以后可以自己做出一款体感游戏,然而后来才发现too young。但是梦想还是要有的,万一实现了呢。趁着paper发出去的这几天,做一个toy demo。研究了一下如何将姿态估计的结果应用于unity,参考了很多资料,最终决定使用UDP协议,让unity脚本接收python脚本的数据(关节点坐标),来达到控制object的目的,由于刚接触unity时间不长(c#也是刚接触的),所以肯定有很多不足,欢迎交流。demo的代码和模型地址https://github.com/bBobxx/MyPoseWithUnity3d

python脚本

Recognition.py,需要安装tensorflow和opencv-python

python脚本这边就是普通的姿态估计的tensorflow程序,只不过要调用socket包,用来发送数据。这边我设定的是

UDP_IP = "127.0.0.1"
UDP_PORT = 5065 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

端口可以更改,只要确定没占用就行。

后面的dataProcess函数是将图片处理成我的网络的输入,这边的姿态估计算法是我论文中的网络,识别率不是很高,但是凑活,相比于那些识别率很高的,速度也快点,在笔记本的cpu上能达到3FPS左右,勉强能用,我这边的模型使用的是cpu,gpu能不能用没测试过,当然这里完全可以换成别的姿态识别模型,最重要的地方是

string_send = 'st,'
for w in range(nr_joint):
string_send += str(x_c[w])+','+str(y_c[w])+','
string_send += 'end'
sock.sendto( string_send.encode(), (UDP_IP, UDP_PORT) )

一定要将数字转换成字符串,并且encode(),当然这里加不加开头和结尾没那么重要,但是加上可以在unity那边判断一下。

c sharp脚本

playerControllerScript.cs, move.cs前者放在Sphere上,后者放在Cube上。

在unity那边首先要建立关节点代表的sphere,我这边是这样设置的,注意sphere的层次关系和名字一定要跟我一样:

cube是为了玩加上去的,可以不用这些。看一下c#这边的接受函数

	private void ReceiveData()
{
client = new UdpClient (port);
while (true)
{
try
{
IPEndPoint anyIP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), port);
byte[] data = client.Receive(ref anyIP);
string text = Encoding.UTF8.GetString(data); //这边记得在解码,port是之前python脚本的端口
string[] strArray = text.Split(',');
int[] coord1 = new int[32];
for (int i = 1; i<strArray.Length-1;++i) {
int x = Int32.Parse(strArray[i]);
coord1[i-1] = x;
}
if (updateCoord) {
coord = coord1;
updateCoord = false;
}
} catch(Exception e)
{
print (e.ToString());
}
}
}

这部分的代码主要参考的这篇博客https://www.raywenderlich.com/5475-introduction-to-using-opencv-with-unity

然后将姿态估计的结果应用到每个小球上就可以了,这里我的demo中将小球和方块添加了刚体和碰撞属性,这部分如果不清楚就去查资料吧,我也是刚入门,就不误导了。这是update函数中干的事情:

	void Update ()
{
if (!updateCoord){
for (int i=0; i<16;i++) {
string obj = "Sphere (" + Convert.ToString(i+1)+")";
GameObject spherei = sphere.transform.Find(obj).gameObject;
if (coord[2*i] >0 && coord[2*i+1]>0) {
int x = coord[2*i]-320;
int y = coord[2*i+1]-240;
spherei.transform.position = new Vector3(x, y, 0.0f);
}
else
spherei.transform.position = new Vector3(-1000.0f, -1000.0f, 0.0f); updateCoord = true;
}
}
}

我的笔记本的相机拍出的图片大小是640*480的,所以上面将x,y坐标减了一半,这里可能需要改,或者直接不减也可以。这里的z坐标是0,是因为这是2d姿态估计,3d的以后如果有结果再实现。

效果图

小球太大的结果QAQ,所以有重叠,真人的话就好点了。编译了一个64位linux的执行文件,链接:[https://pan.baidu.com/s/19P5ebRN7dUXNcN2n7EQLXQ] (https://pan.baidu.com/s/19P5ebRN7dUXNcN2n7EQLXQ) 提取码: ju73。

最新文章

  1. 设计模式-策略模式(Strategy Model)
  2. office 2010 word每次启动都需要配置
  3. Spring之注入的几种方式
  4. Bootstrap中glyphicons-halflings-regular.woff字体报404错notfound
  5. HTML中属性ID和属性NAME有何区别?
  6. makefile使用
  7. Python基础-简单输出
  8. iOS 实时监听app的网络连接状态
  9. css3 shadow为了实现各种漂亮的阴影效果
  10. Nio学习4——EchoServer在IO,NIO,NIO.2中的实现
  11. SVN使用指引(Windows)
  12. java 线程池 ---- newCachedThreadPool()
  13. centos7进单用户
  14. asp .net core Get raw request.
  15. jQuery与js例子
  16. 转:HTML5页面如何在手机端浏览器调用相机、相册功能
  17. mysql 访问不是本地数据库,给用户刷新了权限没有作用
  18. python中__init__()、__new__()、__call__()、__del__()几个魔法方法的用法
  19. IE6 PNG不透明问题 (只解决img标签的图片)
  20. modelsim仿真基本流程

热门文章

  1. linux 设备驱动加载的先后顺序
  2. Orange Pi 3 GPIO 笔记
  3. [Python3]subprocess.check_output() 在python3的输出为bytes而非string,在实际使用过程中得增加一个解码过程decode(),不然会有问题
  4. ansible(一)
  5. H5页面meta标签小结:
  6. 百度地图POI数据爬取,突破百度地图API爬取数目“400条“的限制11。
  7. header头
  8. 2018-2019-2 20165302 《网络对抗技术》Exp4 恶意代码分析
  9. 【转】SVN branches trunk 合并 讲解
  10. ansible role 理解