zoukankan      html  css  js  c++  java
  • 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

    关于图像处理,分享

  • 相关阅读:
    Day10
    Day9
    Day8
    Day 7
    Day-6
    java中的原子性
    java 原子性
    内存可见性
    JVM 常忘笔记
    JVM 解释执行 编译执行 JIT
  • 原文地址:https://www.cnblogs.com/bkycjj/p/3939096.html
Copyright © 2011-2022 走看看