Unity3D Kinect 控制人物模型

两个参考地址:

结合Kinect游戏开发

yuyuyouer工作室

我使用的是unity3D 4.X,kinect SDK为1.7,Kinect1.7UnityPackage.unitypackage(插件包)

  • KinectModelControllerV2 - 你需要将这个脚本拖放到你想要应用kinect控制的模型上。为了让模型能够跟上人的节奏,你需要将模型上控制模型动作的关键骨骼拖放到这个脚本暴漏的合 适的变量中 ,也就是将模型中的骨骼与kincet识别到的人的骨骼绑定起来。另外这个脚本暴漏的变量中,还有一个变量时标识模型是受哪个玩家控制。

模型控制器:KinectModelControllerV2

为使用模型控制器,请按照以下步骤:

  1. 拖拽脚本资源KinectModelControllerV2到场景中的模型中。
  2. 选择场景中的模型。找到模型中的暴漏变量Sw(它代表Skeleton Wrapper). 并将当前场景中的Kinect_Prefab拖拽给Sw这个变量。
  3. 详细展开你的模型,让模型的每一块骨骼在hierarchy面板中可见。
  4. 一个接一个地把模型中的骨骼拖拽到脚本中暴漏的对应的变量中.确保每一个骨骼都对应到了正确的变量上。
  5. 当模型中所有的骨骼都放置好了之后,改变暴漏的Player变量的值,这个变量表明该模型是受哪个玩家控制, 0代表第一个玩家,1 代表第二个玩家。
  6. 接下来要设置暴漏的Mask变量的值。设置合适的值,以决定是所有的骨骼都受Kinect控制,还是仅仅一部分骨骼受Kinect控制.如果这些 受Kinect控制的骨骼都不是你想要的,你可以自己写一个控制模型的脚本来代替KinectModelControllerV2。
  7. 当游戏玩家在控制模型时,如果你想要该模型同时播放自带的动画,那么你需要在暴漏的变量中选中animated选项,并设置BlendWeight变量的值,来决定模型受自带模型动画和Kinect驱动动作的最终混合效果。该变量取值范围为0到1之间。

 关于工作内容介绍

主要两大块:1.人物模型骨架的控制;2.图像数据流的显示

在这之前需要完成准备工作,安装好kinectSDK,导入插件到unity。在整个项目运行之前,会运行kinect,检测安装信息,未安装或未连接都有提示

1.先介绍人物骨架控制

1)导入预制体,它包含了所有的你的世界所需要的脚本开始使用Kinect的空节点-这还不包括控制器,那需要使用实际控制您的机型

2)导入含有骨架信息的3D模型

3)在unity中将AvatarController中人物骨架与变量的申明对应起来

如果拓展到平面的摄像头体感的话,只有二维数组。

2.图像数据流的显示

1)一共显示两个,一个是彩色图,一个是深度图。直接从体感数据流中读取。

2)抠图的话,要在每一帧中计算图像阵列

void UpdateUserMap()
    {
        int numOfPoints = 0;
        Array.Clear(usersHistogramMap, 0, usersHistogramMap.Length);

        // Calculate cumulative histogram for depth 计算深度累积直方图
        for (int i = 0; i < usersMapSize; i++)
        {
            // Only calculate for depth that contains users 只计算深度,包含用户
            if ((usersDepthMap[i] & 7) != 0)
            {
                usersHistogramMap[usersDepthMap[i] >> 3]++;
                numOfPoints++;
            }
        }

        if (numOfPoints > 0)
        {
            for (int i = 1; i < usersHistogramMap.Length; i++)
            {
                usersHistogramMap[i] += usersHistogramMap[i - 1];
            }

            for (int i = 0; i < usersHistogramMap.Length; i++)
            {
                usersHistogramMap[i] = 1.0f - (usersHistogramMap[i] / numOfPoints);
            }
        }

        // dummy structure needed by the coordinate mapper
        KinectWrapper.NuiImageViewArea pcViewArea = new KinectWrapper.NuiImageViewArea
        {
            eDigitalZoom = 0,
            lCenterX = 0,
            lCenterY = 0
        };

        // Create the actual users texture based on label map and depth histogram
        Color32 clrClear = Color.clear;

        for (int i = 0; i < usersMapSize; i++)
        {
            // Flip the texture as we convert label map to color array
            int flipIndex = i; // usersMapSize - i - 1;

            ushort userMap = (ushort)(usersDepthMap[i] & 7);
            ushort userDepth = (ushort)(usersDepthMap[i] >> 3);

            ushort nowUserPixel = userMap != 0 ? (ushort)((userMap << 13) | userDepth) : userDepth;
            ushort wasUserPixel = usersPrevState[flipIndex];

            //test
            //ushort userMap = (ushort)(usersColorMap[i] & 7);
            //ushort userColor = (ushort)(usersColorMap[i] >> 3);

            //ushort nowUserPixel = userMap != 0 ? (ushort)((userMap << 13) | userColor) : userColor;
            //ushort wasUserPixel = usersPrevState[flipIndex];

            // draw only the changed pixels
            if(nowUserPixel != wasUserPixel)
            {
                usersPrevState[flipIndex] = nowUserPixel;

                if (userMap == 0)
                {
                    usersMapColors[flipIndex] = clrClear;
                }
                else
                {
                    if(colorImage != null)
                    {
                        int x = i / KinectWrapper.Constants.ImageWidth;
                        int y = i % KinectWrapper.Constants.ImageWidth;

                        int cx, cy;
                        int hr = KinectWrapper.NuiImageGetColorPixelCoordinatesFromDepthPixelAtResolution(
                            KinectWrapper.Constants.ImageResolution,
                            KinectWrapper.Constants.ImageResolution,
                            ref pcViewArea,
                            x, y, usersColorMap[i] /*usersDepthMap[i]*/,
                            out cx, out cy);
                        //colorStreamHandle,ref usersColorMap[i],ref colorImage

                        if(hr==0)
                        {
                            int colorIndex = cx + cy * KinectWrapper.Constants.ImageWidth;

                            //this.usersHistogramMap[colorIndex] = -1;
                            //this.usersHistogramMap[colorIndex-1] = -1;

                            colorIndex = usersMapSize - colorIndex - 1;
                            //colorIndex=287649;
                            //0-300000
                            //colorIndex=200000+1600*Convert.ToInt32(DateTime.Now.Second.ToString());
                            float histDepth = usersHistogramMap[colorIndex];
                            colorIndex = Convert.ToInt32(histDepth);

                            if(colorIndex >= 0 && colorIndex < usersMapSize)
                            {
                                Color32 colorPixel = colorImage[colorIndex];//colorIndex
                                usersMapColors[flipIndex] = colorPixel;//   new Color(colorPixel.r / 256f, colorPixel.g / 256f, colorPixel.b / 256f, 0.9f);

                                //usersMapColors[flipIndex].a = 230; // 0.9f

                            }
                        }
                    }
                    else
                    {
                        // Create a blending color based on the depth histogram
                        //float histDepth = usersHistogramMap[userDepth];
                        //Color c = new Color(histDepth, histDepth, histDepth, 0.9f);

                        //switch(userMap % 4)
                        //{
                        //    case 0:
                        //        usersMapColors[flipIndex] = Color.red * c;
                        //        break;
                        //    case 1:
                        //        usersMapColors[flipIndex] = Color.green * c;
                        //        break;
                        //    case 2:
                        //        usersMapColors[flipIndex] = Color.blue * c;
                        //        break;
                        //    case 3:
                        //        usersMapColors[flipIndex] = Color.magenta * c;
                        //        break;
                        //}
                    }
                }

            }
        }

        // Draw it!
        usersLblTex.SetPixels32(usersMapColors);

        if(!DisplaySkeletonLines)
        {
            usersLblTex.Apply();
        }
    }

UpdateUserMap

关于图像处理,分享

时间: 2024-10-06 08:35:08

Unity3D Kinect 控制人物模型的相关文章

[Unity3D]Unity3D游戏开发之使用EasyTouch虚拟摇杆控制人物移动

大家好,欢迎大家关注我的博客,我是秦元培,我的博客地址是blog.csdn.net/qinyuanpei.今天呢,我们来一起学习在Unity3D中使用EasyTouch虚拟摇杆来控制人物移动.虽然Unity3D内置了一个Joystick组件(事实上就是一个GUITexture和一个Js脚本文件啦),但是博主在实际使用的时候发现这个内置的Joystick存在无法适应屏幕大小的问题,所以博主在这里向大家推荐使用EasyTouch这个插件,通过这个插件.我们能够高速地在应用中集成虚拟摇杆功能,并且能够

时光煮雨 Unity3D实现2D人物移动-总结篇

系列目录 [Unity3D基础]让物体动起来①--基于UGUI的鼠标点击移动 [Unity3D基础]让物体动起来②--UGUI鼠标点击逐帧移动 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现 时光煮雨 Unity3D实现2D人物动画① UGUI&Native2D序列帧动画 时光煮雨 Unity3D实现2D人物动画② Unity2D 动画系统&资源效率 背景 最近研究Unity3d,2d寻路的实现.所以又一次涉及到了角色坐标位移的问

用3dMax给lol人物模型制作表情动画并导入Unity

参考链接:Blend Shapes / Morph Targets for Facial Animation (Autodesk 3ds Max) 今天逛Youtube的时候Get到了一个新技能:那就是给人物制作表情动画,感觉超简单! 制作Unity中可用的人物表情动画流程大致是:在3dMax中制作表情动画->导出成FBX文件->导入Unity 下面以制作微笑和眨眼睛的动画为例进行讲解 在3dMax中制作表情动画 首先导入人物模型,这里以亚索为例: 按住Shift,选择移动工具将当前选中的亚索

关于用过控制人物移动的方法

在这里将收集更新有关,控制移动的方法. 1.通过WSAD控制人物的前后移动的方法(一) 1 public class PlayerMovemeng:monoBehaviour 2 { 3 //人物的移动速度 4 public float speed=6f; 5 //坐标的移动变化量 6 Vector3 movement; 7 Rigidbody playerRigidbody; 8 //与Ray发生碰撞的平面的Layer层数' 9 int FloorMask; 10 float camRayLe

利用OnAnimatorove函数控制人物的移动

unity中控制人物移动有很多方法,经过这么长时间的学习后,我总结了一些: 利用transform的translate方法控制人物移动:(结合动画的控制就不说了)  float mx = Input.GetAxis("Horizontal") * moveSpeed * Time.deltaTime;  float mz = Input.GetAxis("Vertical") * moveSpeed * Time.deltaTime;    transform.tr

Unity3d Animator控制动画按帧运行

昨天同事想控制一个角色射箭动画,在拉弓的时候想用代码控制人物拉弓的整个过程,查了一下API,方法很简单Animator.StartPlay()(http://wiki.ceeger.com/script:unityengine:classes:animator:animator.startplayback),使用Animator.StopPlayback()停止动画器播放模式.当播放停止时,Avatar恢复从游戏逻辑获得控制权 Example: 1 using UnityEngine; 2 us

皇家每羊历险记(三)——人物模型的导入与动画

人物模型采用的是Unity官方的一个人物模型,至于其他的npc模型目前正在寻找中,整个人物模型中包含了许多动作,但是这个游戏只需要 闲置状态(Idle),走路状态(Walk),奔跑状态(Run)和死亡状态(Die),先将任务模型拖入Hierarchy中 然后创建AnimatorController,命名为PlayerController,这个动画控制器相对来说比较简单,先来设置参数,打开windows-Animator窗口,创建一个float变量Speed,然后创建一个bool变量Dead来决定

lol人物模型提取(二)

??两个dds文件怎么导入到一个模型上呢?这模型又不能拆开. ??一开始我想的是用两个材质球来完成,一个材质球对应一个dds文件,然而行不通. ??一个材质球对应两个dds文件还不太会弄,于是我想着干脆把两个dds文件合并为一个,用ps再下个可以打开dds文件的插件就可以实现该操作,不过效果并不是我想象的那样,上面那层dds图像直接把下面那层给盖住了,结果还是只能显示一个dds文件的贴图. ??查了半天终于知道怎么用一个材质球贴两个dds文件了.不过并没有什么卵用,达不到我想要的效果. ??没办

ANDROID应用中嵌入Unity3D视图(展示3D模型)

效果展示:                 开篇废话: 我现在所在的Team每周需要一个人给大家介绍一个知识点,或者新技术.这礼拜正好轮到我了,由于我工作才一年,面对那帮老鸟讲知识点感觉有点作死.所以我就准备选个新技术介绍一下. 由于我在大学里自学过一段时间Unity3D,所以我想介绍的技术就是它,但我现在做的是应用开发,不能做个小游戏去给大家演示.所以我想到比较简单,直观,而且有可能真正能用到的就是在Android应用中展示3D模型.比如在产品展示时直接把这个产品的3D模型展示出来而不是个图片