首页 > 编程知识 正文

虚拟现实软件开发(python能搞vr吗)

时间:2023-05-05 22:44:22 阅读:87300 作者:4860

作者| ctdxmy

展出| AI技术基地营(ID:rgznai100 ) () ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) ) )。

随着

引言

人机交互技术的迅速发展,人体姿态估计技术越来越受到重视。 姿态估计作为人体行为识别的重要组成部分,近年来已成为计算机视觉领域的重要研究热点。 由于人体结构和姿态的复杂性以及视觉理论的局限性,最初的人体姿态估计算法只能从图像或视频中预测人体二维骨骼节点的坐标位置。 2015年马普提出的由姿势和体型参数驱动的蒙皮多人线性模型,具有很好的建模效果和快速的计算效率,因此很多团队提出了利用该模型进行人体姿势估计的方法。 目前,基于人体变形模型的姿态估计方法可以根据两个标准进行分类。 一种是基于优化的方法,另一种是基于回归的方法。 并且,预计最终发展到现在的三维人体姿态也越来越成熟。

今天,我们将使用Python Unity3D实现基于threedposeunitybarracuda (数字标准版,Ltd.)的3d虚拟现实交互式游戏。 这里的目的是结合Unity3D和python的三维姿态估计模型,实时获取人体的三维坐标,将坐标与人体模型的骨骼联系起来控制3d角色。 在这一步中添加3D模型,设定基本的触摸逻辑,可以达到我们设定的简单游戏的目的。 这里使用的模型可以用3Dmax和Blender绘制。 最终的演示效果如下。

三维姿态控制介绍

基于三维姿态的估计,对使用unity实时获取的三维骨骼坐标和角色骨骼的绑定,控制角色动画,达到互动性的效果。

1.1三维姿态估计介绍

人体姿态估计的主要任务是预测人体关节点的三维坐标位置和角度等信息。 由于人体姿态标记数据集不足,许多研究方法都基于2D人体姿态估计方法,2D人体姿态估计研究的发展也为3D人体姿态估计奠定了基础,3D人体姿态估计研究具有很大的潜力。

在实际应用中,3D姿态估计是2D姿态估计加上深度信息,由于人体姿态的表达比2D准确,其应用范围和研究价值比2D人体姿态估计高,但3D姿态估计难度也高,遮挡、单视点2D到3D映射固有的深度模糊性、不舒适性、大型户外空间

目前的研究中,三维人体姿态估计方法可以分为传统方法和深度学习方法两种。 在深度学习方法广泛应用之前,3D人体姿态注释数据集和高运算能力的GPU还没有普及,研究者主要用传统的计算机视觉和机器学习领域应用的几种方法进行了3D人体姿态的估计。 传统的三维人体姿态估计和基于深度学习的姿态估计之间最明显的特征是是否是使用多层神经网络的学习方法。 建模方式不同,估计精度、计算复杂度等也存在较大差异。 其中建模是三维人体姿态估计的重要方面,目的是表征从输入数据中提取的关键点和特征。 在解决实际问题时,由于实验个体所处环境的复杂性,模型制作的难度大幅上升,因此选择合适且有效的图像特征来简化模型制作过程至关重要。 由于传统方法大多采用基于人体模型的方法描述估计人体姿态,通过算法提取图像姿态的特征,所以对特征表示和关键点的空间位置关系这两个维度有较高的要求,除了边界、颜色等低级特征外,典型的是尺度不变特征变化梯度直方图等表现能力更强,具有可以有效压缩特征空间维度的高水平特征,它们在时间效率方面有优势,但仍是人工设计的传统特征,有很大的存在

1.2 ThreeDPoseUnityBarracuda介绍

ThreeDPoseUnityBarracuda通过读取Barracuda的onnx三维姿态估计模型,可以在Unity中进行三维姿态估计。

程序设计

此处的三维姿势推算使用resnet 34 _3inputs _ 448 x448 _ 2020 06 09.onnx模型。 unity3D是对onnx模型的调用,它同时构建了三维场景和设计逻辑的规则。

2.1三维姿态估计模型分析

这里使用的三维姿势,我想在之前的文章“基于3DPose的三维人体姿势识别”中有所介绍,不做过多说明。

使用onnxruntime读取“resnet 34 _3inputs _ 448 x448 _ 2020 06 09.onnx”模型文件,对想要实时识别的图像数据,输入每张图像的

offset图和heatmap图。通过找到第j个关节的28个特征图,并找到最大值的索引来获取个点坐标。并把坐标按照一定比例缩放。使得图像变形较为符合人体规律。

for j in range(0, 24): # 找到第j个关节的28个特征图,并找到最大值的索引 joint_heat = heatMap3D[j * 28:(j + 1) * 28, ...] if np.max(joint_heat)>0.1: print(np.max(joint_heat)) [x, y, z] = np.where(joint_heat == np.max(joint_heat)) x = int(x[-1]) y = int(y[-1]) z = int(z[-1]) # 通过heatmap的索引找到对应的offset图,并计算3D坐标的xyz值 pos_x = offset3D[j * 28 + x, y, z] + x pos_y = offset3D[24 * 28 + j * 28 + x, y, z] + y pos_z = offset3D[24 * 28 * 2 + j * 28 + x, y, z] + z kps[j, 0] = pos_x kps[j, 1] = pos_y kps[j, 2] = pos_z else: try: kps[j, 0] = kps[j-1, 0] kps[j, 0] = kps[j-1, 0] kps[j, 2] = kps[j-1, 2] except: pass parent = np.array([15, 1, 2, 3, 3, 15, 6, 7, 8, 8, 12, 15, 14, 15, 24, 24, 16, 17, 18, 24, 20, 21, 22, 0]) - 1; for i in range(len(kps)): if (parent[i] != -1): ax.plot3D(kps[[i, parent[i]], 0], -kps[[i, parent[i]], 1], -kps[[i, parent[i]], 2], 'gray')

2.2 unity3D程序设计

Unity3D这里主要使用到了三维场景搭建和CS脚本制定逻辑,这里场景搭建,在搭建好模型后手动规划即可。主要介绍程序部分。

1、读取模型,按照下图配置即可:

2、随机从天空掉落物体CS脚本:

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Randomoccurs : MonoBehaviour { //随机产生的物体 private static GameObject sphere; private static GameObject cube; private static GameObject cylinder; private static GameObject capsule; public GameObject[] gameobject = { sphere, cube, cylinder, capsule }; //想要产生几波 public int waves; //每波产生的数量 public int values; //产生之后延迟时间 public float spawnwait ; // Use this for initialization void Start() { StartCoroutine(test01()); } void Update() { } // Update is called once per frame IEnumerator test01() { for (int j = 0; j < waves; j++) { for (int i = 0; i < values; i++) { Instantiate(gameobject[Random.Range(0, 4)], transform.position, transform.rotation); } yield return new WaitForSeconds(spawnwait); } } } 3、制定触碰规则,碰到门,门对应ID设置为销毁,碰到掉落物体,分数加分: using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class hit_obj : MonoBehaviour { // Start is called before the first frame update static public int score = 0; void Start() { } // Update is called once per frame void Update() { } // 碰撞开始 void OnTriggerEnter(Collider collider) { var tag = collider.tag; if (collider.tag == "body_center") { score += 1; GameObject.Destroy(gameObject); //GameObject.Destroy(gameObject, 2.0f);//摧毁自身 } Debug.Log(score); GameObject.Find("Canvas/Score").GetComponent<Text>().text = "得分:"+score.ToString(); if (collider.tag == "ground") { //Debug.Log("销毁" + gameObject.tag); GameObject.Destroy(gameObject); } } // 碰撞结束 void OnTriggerStay(Collider collider) { } // 碰撞持续中 void OnTriggerExit(Collider collider) { } }

完整代码:

链接:

https://pan.baidu.com/s/1hZ5f-4Vv12rpJXK5XL_t5A

提取码:7q6o

ctdxmy,CSDN博客专家,CSDN达人课作者。硕士在读于中国矿业大学,开发有taptap竞赛获奖等。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。