一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Unity5 利用Kinect Studio 和Gesture Builder建立自定義姿勢分類器

 文清陽 2020-07-07

Unity升級到5以后,好多以前使用的插件都用不了了,比如,以前利用Kinect來辨別姿勢的話,直接可以使用Kinect with MS-SDK (https://www.assetstore./en/#!/content/7747),就可以利用這個package里面的函數(shù)就可以完成一些動作的捕獲,是不是,自從使用Unity5之后,這個包導(dǎo)入就會報編譯錯誤了?嗯,既然,別人的庫不能用了,那我們就自己建立一個自己的分類器,這樣的話,不僅可以完成一些基本的姿勢識別,我們還可以定義任意多的姿勢!
說到分類器,或許有人會說,那不是機器學(xué)習(xí)訓(xùn)練樣本之后制造的東西嘛?沒錯,的確是利用機器學(xué)習(xí)的方式來建立分類器。機器學(xué)習(xí)的算法太復(fù)雜了,我不會怎么辦?那么,我介紹的方法剛好適合你!因為微軟已經(jīng)給我們做好了對應(yīng)的應(yīng)用程序,我們只要訓(xùn)練樣本就好啦!
好的,來介紹一下我們的工具,Kinect Studio 和 Visual Gesture Builder,這兩個程序應(yīng)該在我們下載 Kinect v2 的SDK的時候就已經(jīng)下載下來了。

一 Kinect Studio 收集視頻樣本

  1. 首先,打開Kinect Studio,先點擊File進入設(shè)置界面,這里我們可以設(shè)置我們的視頻片段存儲位置。

  2. 錄制視頻樣本,先轉(zhuǎn)到Record界面,連接Kinect
    這里寫圖片描述

  3. 成功之后,我們的Kinect的三個紅外燈應(yīng)該是亮了,然后點擊那個紅色的icon開始錄制視頻。
    這里寫圖片描述

  4. 我們這里以揮手這個動作來作為例子,我們站在一個合適的位置,做揮手的動作,一開始慢慢的,多做幾組),然后錄制完畢,點擊停止錄制。
    這里寫圖片描述

  5. 這時候,Kinect Studio 的界面會自動跳轉(zhuǎn)到Play的界面。我們先Disconnect Kinect之后,可以點擊play的icon來查看這個視頻例子,注意,我用紅色方框框起來的部分,這個就是保存的文件名,注意,只要我們點擊了錄制,Kinect Studio都會給我們自動保存的。保存的位置就是我們剛才設(shè)置的文件夾,如果,你沒有設(shè)置的話,可以去File 的Setting里面看看它的默認文件夾的位置。
    這里寫圖片描述

  6. 同樣的操作,我們在做幾遍,當然你的視頻樣本越多,我們生成的分類器就更準確啊。

####二 Visual Gesture Builder制作正負樣本

  1. 打開軟件,F(xiàn)ile -> New Solution, 自己隨便命個名,我這里叫做DemoWave。

  2. 現(xiàn)在的面板李應(yīng)該出現(xiàn)了你剛才project,右鍵這個工程,選擇Create New Project With Wizard。
    這里寫圖片描述

  3. 出現(xiàn)VGB Gesture Wizard 的界面,點擊 Next
    這里寫圖片描述

  4. 給我們的姿勢命個名,我這里叫做demowave。
    這里寫圖片描述

  5. 這里是判斷我們的姿勢是否包含下半身的骨骼,因為我們只是揮手,腿部做什么動作都可以,所以,選擇不包含。
    這里寫圖片描述

  6. 這里是判斷我們的姿勢是否需要判斷特定的手勢。因為我們揮手主要是看胳膊的動作,所以,不關(guān)心手部的動作,這里也選擇不包含。
    這里寫圖片描述

  7. 這里是讓我們來選擇需要判斷的骨骼的部分,每個圖旁邊都有一定的注解說它忽略了什么,我這里就不一一翻譯了,因為我們判斷的是揮手,所以,左右手都是需要判斷的,但是不需要判斷下半身的狀態(tài),所以,我們選擇第一個joint mask就好。
    這里寫圖片描述

  8. 這里是問我們的動作判斷是否是區(qū)分左右的?那我們的揮手動作為例,如果我們選擇NO,那么Kinect判斷揮手的時候,就不區(qū)分是左胳膊懂還是右胳膊動;如果我們選擇YES的話,那么Visual Gesture Builder就會給我們建立兩個Project一個叫做demowave_Right,另外一個叫做demowave_Left,就相當于建立兩個分類標準,用于區(qū)分左右手。
    這里寫圖片描述

  9. 這個界面主要是來判斷我們的動作是否是連續(xù)性的還是離散的。所謂離散性質(zhì),就是判斷這個我們動作“發(fā)生了“還是“沒有發(fā)生“,就是一個1還是0的判斷,如果連續(xù)性質(zhì)的話呢,就是判斷Kinect檢測到的姿勢和我們分類器的姿勢的吻合度有多少,它不是一個是否的判斷而是一系列的數(shù)字來表示當前的姿勢和分類器姿勢的重合度,而且,這個數(shù)字越高,表示當前檢測的動作和分類器的標志動作越像。而我們這里指向判斷用戶是否揮動了左手還是右手,是一個是否的判斷,所以我們這里選擇NO。
    這里寫圖片描述

  10. 這里就是說,下面會有這兩個gesture會被創(chuàng)建。因為我們在之前選擇了左右的判斷,所以這里會出現(xiàn)兩個getures如果剛才我們沒有選擇左右的判斷,那么這里只會出現(xiàn)一個gesture。
    這里寫圖片描述

  11. 點擊confirm,就會生成對應(yīng)的工程,現(xiàn)在我們的工程如下圖所示。
    這里寫圖片描述

    這里簡單的說一下,一共是兩個工程有四個文件生成,所以呢,就是每個gesture右兩個文件,這兩個文件名字都是一樣的,只不過一個是.a結(jié)尾的,一個不是,那么.a結(jié)尾的文件呢,其實是測試gesture的一個文件,而那個不帶.a的才是我們拿來訓(xùn)練的樣本?;旧夏?,我們是那樣本數(shù)目的2/3用來訓(xùn)練樣本,1/3就是放在那個.a 文件下,用來測試分類器的。

  12. 好的,下面,我們來利用剛才收集到的視頻片段來創(chuàng)建正負樣本。右鍵,demowave_Left,選擇Add Chip,把我們剛才錄的視頻片段加入進去。(建議大家錄完視頻片段之后給它們改個名字,這樣便于管理,當然,我說是視頻片段,這里的視頻片段其實是包含了Kinect的骨骼等數(shù)據(jù)的)
    這里寫圖片描述

  13. 我們把視頻片段(也就是Chips)加入進去之后,然后告訴訓(xùn)練器哪些幀時正樣本,哪些幀時負樣本。其中正樣本被藍色的線標志出來了,這里需要手動判別正負樣本,當然,對一段視頻操作當然是少不了快捷鍵啊。尷尬的是,默認打開的窗口(也就是你們現(xiàn)在展示的窗口)是看不到快捷鍵提示的。那么我們只要把下面的Gesture Tags的區(qū)域拉大一點,是不是看見下面的快捷鍵提示啦?(為了避免出現(xiàn)誤判的情況,除了收集足夠多的正樣本之外,我們還需要各種各樣的負樣本,如圖,我們在做一個揮手的樣本收集,我在錄制視頻的時候還跳動幾下,用作負樣本)
    這里寫圖片描述

  14. 然后,我們依次把每個Chips的政府樣本都設(shè)置好之后。我們可以選擇總的工程文件,右鍵Build,當然,你已經(jīng)迫不及待的想看看當前姿勢的訓(xùn)練情況,你也可以選擇某一個Gesture文件右鍵Build。然后就是等待的過程,這個時間取決于樣本的多少,因為我這里只有6個視頻片段,所以訓(xùn)練時間很短。

  15. 當你發(fā)現(xiàn)下面的Output欄中出現(xiàn)build完成的提示,并且沒有錯誤的話,那么恭喜你,你自定義姿勢的分類器已經(jīng)訓(xùn)練完成了。

  16. 還記得那個.a文件嘛?如果你還有沒有訓(xùn)練的視頻片段的話,可以把那個視頻片段加入你的.a文件下,來測試分類器。當然,你也可以右鍵工程選擇Live Preview,這樣的話,Visual Gesture Builder就會打開Kinect,就會捕捉你的動作,實時的判斷當前的動作是否符合條件。旁邊的那個方框里面的數(shù)值(類似直方圖)越高,說明你的動作越符合分類器。
    這里寫圖片描述

  17. 訓(xùn)練完成之后,我們會得到一個.gba的文件,這個就是我們訓(xùn)練出來的分類器!

三 Unity5 中調(diào)用分類器

  1. 首先創(chuàng)建一個Unity的工程,導(dǎo)入Kinect Unity的開發(fā)包。
    什么?不知道怎么使用Unity5 +Kinect v2,好吧,這又一個step by step的教程
    http://www./blog/2015/03/27/unity-5-and-kinect-2-integration/
  2. 在我們的工程文件(Assets)下面創(chuàng)建一個文件夾叫做StreamingAssets,然后把我們剛才生成的分類器文件(.gba文件/.gbd文件)放進去。
  3. 創(chuàng)建一個腳本GestureSourceManger.cs里面的代碼如下:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Windows.Kinect;
using Microsoft.Kinect.VisualGestureBuilder;
public class GestureSourceManager : MonoBehaviour {
public BodySourceManager _BodySource;
public string databasePath;
private KinectSensor _Sensor;
private VisualGestureBuilderFrameSource _Source;
private VisualGestureBuilderFrameReader _Reader;
private VisualGestureBuilderDatabase _Database;
// Gesture Detection Events
public event GestureEvent OnGesture;
private static GestureSourceManager instance = null;

public static GestureSourceManager Instance{
	get{
		return instance;
	}
}

// Use this for initialization
void Start() {
_Sensor = KinectSensor.GetDefault();
if (_Sensor != null) {
if (!_Sensor.IsOpen) {
_Sensor.Open();
}
// Set up Gesture Source
_Source = VisualGestureBuilderFrameSource.Create(_Sensor, 0);
// open the reader for the vgb frames
_Reader = _Source.OpenReader();
if (_Reader != null) {
_Reader.IsPaused = true;
_Reader.FrameArrived += GestureFrameArrived;
}
// load the ‘Seated’ gesture from the gesture database
string path = System.IO.Path.Combine(Application.streamingAssetsPath, databasePath);
Debug.Log ("database path is "+path);
_Database = VisualGestureBuilderDatabase.Create(path);
// Load all gestures
IList gesturesList = _Database.AvailableGestures;
for (int g = 0; g < gesturesList.Count; g++) {
Gesture gesture = gesturesList[g];
Debug.Log ("database name is "+ gesture.Name);
_Source.AddGesture(gesture);
}
}
instance = this;
}
// Public setter for Body ID to track
public void SetBody(ulong id) {
if (id > 0) {
_Source.TrackingId = id;
_Reader.IsPaused = false;
Debug.Log ("id is "+id);
} else {
_Source.TrackingId = 0;
_Reader.IsPaused = true;
}
gameObject.GetComponent ().AddGesture ();
}
// Update Loop, set body if we need one
void Update() {
if (!_Source.IsTrackingIdValid) {
FindValidBody();
}
}
// Check Body Manager, grab first valid body
void FindValidBody() {
if (_BodySource != null) {
Body[] bodies = _BodySource.GetData();
if (bodies != null) {
foreach (Body body in bodies) {
if (body.IsTracked) {
SetBody(body.TrackingId);
break;
}
}
}
}
}
/// Handles gesture detection results arriving from the sensor for the associated body tracking Id
private void GestureFrameArrived(object sender, VisualGestureBuilderFrameArrivedEventArgs e) {
VisualGestureBuilderFrameReference frameReference = e.FrameReference;
using (VisualGestureBuilderFrame frame = frameReference.AcquireFrame()) {
if (frame != null) {
// get the discrete gesture results which arrived with the latest frame
IDictionary<Gesture, DiscreteGestureResult> discreteResults = frame.DiscreteGestureResults;
if (discreteResults != null) {
foreach (Gesture gesture in _Source.Gestures) {
if (gesture.GestureType == GestureType.Discrete) {
DiscreteGestureResult result = null;
discreteResults.TryGetValue(gesture, out result);

						if (result.Confidence > 0.05) { 
						// Fire Event 
						if(OnGesture!=null){
							Debug.Log("Detected Gesture " + gesture.Name + " with Confidence " + result.Confidence);
							OnGesture(this,new KinectGestureEvent(gesture.Name, result.Confidence));	
						} 
					}
				} 
			} 
		} 
	} 
}

}
}
```
4. 然后在外部調(diào)用這個代碼,注意:這個腳本是必須傳入一個BodyManager對象的,還要寫一下我們的分類器的名稱(當然,這個你在腳本里面hardcode也可以)。
這里寫圖片描述

  1. 現(xiàn)在,點擊運行,揮一下手,你就會發(fā)現(xiàn),控制欄有輸出啦!

我這里有一個KinectMLTest的工程,感興趣的朋友,可以下載看看~
傳送門:https://github.com/ArlexDu/UnityKinectMLTest

參考鏈接:
[1]https://channel9./Blogs/k4wdev/Custom-Gestures-End-to-End-with-Kinect-and-Visual-Gesture-Builder
[2]https://channel9./Blogs/k4wdev/Custom-Gestures-End-to-End-with-Kinect-and-Visual-Gesture-Builder-part-2-
[3]https://blog./post/kinect-2-0-unity-5-membuat-gesture-discrete-mode-dengan-visual-gesture-builder/
[4]https://social.msdn.microsoft.com/Forums/en-US/42a4059a-e8b4-4ffd-87e7-757e19dcd7ca/how-to-load-a-vgb-database-with-unity-plugin?forum=kinectv2sdk#4c895477-b120-4806-9f3c-5930b07ac8a1

2020.6.27更新
距離當初做這個小探索已經(jīng)過去三年多了,好多細節(jié)也比較生疏… 可能無法及時回復(fù)有問題的小伙伴,其實我這個博文的主要參考來源就是我提供的這4篇參考文獻,如果有問題的話也可以去看一下那幾個鏈接…我這次也做了部分更新,在原有的倉庫中增加了unity 2018的分支,希望可以在大家電腦上正常運行:
https://github.com/ArlexDu/UnityKinectMLTest/tree/unity_2018

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    又色又爽又无遮挡的视频| 亚洲欧美日本视频一区二区| 太香蕉久久国产精品视频| 五月婷婷六月丁香狠狠| 邻居人妻人公侵犯人妻视频| 亚洲一区二区精品免费视频| 日本免费一级黄色录像 | 国产又黄又猛又粗又爽的片| 午夜精品在线视频一区| 成人午夜在线视频观看| 美女激情免费在线观看| 91精品国产品国语在线不卡| 久久三级国外久久久三级| 欧美成人黄色一级视频| 国产成人精品视频一二区| 日韩精品少妇人妻一区二区| 精品al亚洲麻豆一区| 两性色午夜天堂免费视频| 成人国产一区二区三区精品麻豆| 国产精品日韩精品最新| 国产一区二区精品高清免费| 韩国日本欧美国产三级| 国产精品欧美在线观看| 亚洲av秘片一区二区三区| 99久久精品国产日本| 大香蕉精品视频一区二区| 国产精品免费无遮挡不卡视频| 国产精品欧美日韩中文字幕| 91一区国产中文字幕| 国产av一区二区三区麻豆| 色婷婷激情五月天丁香| 欧美午夜色视频国产精品| 国产精品欧美激情在线播放| 亚洲a级一区二区不卡| 国产欧美日韩在线精品一二区| 精品人妻av区波多野结依| 亚洲精品一二三区不卡| 欧美精品亚洲精品一区| 欧美一级特黄特色大色大片| 国产女同精品一区二区| 青青操在线视频精品视频|