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

關於圖像處理,分享

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM