這篇是關於自訂手勢 Static Gesture
在之前有提到骨架資訊
Adobe AIR + Kinect (2) - Skeleton with 2D Character
首先感謝Gray Liao 在 Some extensions for AIRKinect
一系列相關文章中給了我許多啟發與學習經驗,再次感謝。
目標:
比出 O & X的手勢來讓LED燈隨之亮滅。
來練習如何用自訂手勢來與Arduino互動吧!
AS
Custom Static Gesture 自訂靜態手勢:Bingo & Cross
Bingo
達成Bingo手勢的條件
◎ 雙手要高過頭部 (也不能過高,不然也不像圓圈 )
◎ 雙手要接近一定距離 (不要完全貼合)
在測試中發現手掌翻轉時會導致手部骨架位置資訊的變化,
結論是手心不要朝向螢幕,而是向下的角度完成(類似敬禮,如上圖)。
Cross
達成Cross手勢的條件
◎ 雙手不可高過頭頂 (約肩膀高度上下)
◎ 雙手交叉的位置靠近另一邊肩膀 (右手在左肩)
測試中發現了一些小細節,
當只是先計算單手靠近另一邊肩膀的距離值,
與雙手交叉靠近另一邊肩膀所得到的數據不同。
這應該是當做出交叉動作時,
Shoulder也會因為Hand 的關係(牽引)而有些許移動。
AS3 Connec to Arduino
使用as3Glue程式庫來與Arduino(實際上是SerProxy)連線,
並把Flash的訊息包裝成Firmata。
也可以同時參考這裡。
Arduino
Arduino + LED (設定pin 13, 不附圖XD)
Arduino Code
SerProxy (記得要開啟呀)
====================
心得
====================
坦白說自己寫的靜態手勢判斷算法並不嚴謹(只是判斷是否在預設範圍內而已),
雖然預設是站著時判斷是否比出手勢,
但發現坐著coding時, 有時會莫名發生判定成功的情形XD
看來日後在設計時必須考慮更細微的使用情境會更好。
動作設定必須合理 & 清楚界定範圍:
在判定不相對嚴謹的情況下,
(要求嚴謹得要考慮更多種可能&實用性,只是實驗性質的判斷還不需要那麼複雜)如果有多種以上的動作偵測,更要留意誤判的可能性。
即使不是做出A,但不經意的動作也有可能導致觸發。
接近的Gesture最好不要在同一個情境下作多種事情,導致模稜兩可。
(此例的Bingo/Cross = ON/OFF,但別又同時擁有其他功能。)
使用的數據類型是 position.world (3D position in world coordinate space)
判斷的數值會因為與鏡頭距離的不同而有所差異。
所以假設使用情境下,
應該要求User與Kinect 保持在一定距離,
好讓判斷能夠收斂在固定範圍內。
我想不論是其他偵測動作的算法或感應器,這都應該是必備條件。
(不然距離太遠、不經意做出的動作而導致誤判,也是非常可能的。)
另外,position沒有另外與depth, rgb 比較,
不知在不同情況下是否可以採取對應的數據類型。(留待日後再研究吧XD)
Gesture手勢的應用
Github上的類別庫 NuiGesture
作者將所有的功能都封裝在裡面
因此只要這樣(↓)便可以使用,快速上手。
使用心得:
測試時發現感應太過靈敏了,就算只是身體移動也會被判定有資訊輸入(這樣很困擾欸)。
只要調降 NuiSettings.ActionCatchTime 的數值就可以了。
有時仍有誤判可能(例:不是正常站姿),是較為美中不足之處。
NuiGesture 這個類別庫最大優勢在於,
可以輕鬆整合進自己的程式碼,
能夠進行基礎手勢「上、下、左、右」的方向判斷。 (左右手皆可, 預設只有開放右手)
便能開發基於此的更多體感互動應用。
使用肢體的自然姿勢,Gesture 能有很多種應用。
講到上下左右,最容易聯想到的還是小時候做過的視力檢查吧!
搭配 NuiGesture,做了個視力檢查的小遊戲,
玩玩看你的視力如何!?
影片請看我。
BTW, 關於視力檢查的美國用語
Skeleton
Kinect有使用者骨架的偵聽事件,當User進入到攝影鏡頭範圍時約略等待一會就能觸發。
搜尋一下也能看到前輩們關於骨架的描述教學,操作細節便不贅述了。
[教學] AIRKinect 的魔法帽子
AIRKinect [4] Skeleton 使用者骨架擷取
節錄重點:
1. Kinect最多可同時擷取6人,其中2人全身共20個骨架節點(SkeletonJoint),另外4人只有核心節點。(後者看來實用性較不高)
雖然有擷取上半身的設定,不過測試時可能距離鏡頭太近,還是得站起來才能被辨識。
(抑或是這本來就是得讓User Skeleton先完整被偵測到才行!?)
2. 測試時解析度採用RGB預設640*480,下半身節點可能因為距離&電腦桌的關係導致對位不準確。似乎不太要緊,因為以用途看來沒有上半身節點來得多。(所以管他的呢!)
3. 骨架資訊應用的範圍很多,可說AIRKinect ANE有最大應用範圍的就是Skeleton,
除了上圖可以看到根據骨架位置貼上偷蛋豬之外XD,做個簡單的AR也就不是太難的事情。
更有甚者,根據骨架節點與節點之間的相對位置去判斷是否為靜態姿勢,
or擷取連續時間內根據節點路徑(或說軌跡)來判斷是否為手勢(Gesture)或其他姿勢。
以此就能有更多豐富的互動操作方式,
但這又是另外一回事囉......ANE內沒有這樣的feature。
在Github上遍尋關於AIRKinect Gesture的相當稀少且有限制(當然嘛....)。想必native C++, C# 的高手們也早就開發出對應於Kinect的眾多gesture or posture library。要有Gesture必須要靠自己完成,只能留待後話了.....(意思就是現在沒空&難度也不低)
言歸正傳
既然談到Skeleton,也許會想到是否User做甚麼動作,讓腳色也跟著一起動作呢?
答案是可以,但並不如想像中美好。
先解釋一開始測試的思路,單純的以為只要把腳色的肢體對應到人體上,
那麼User做甚麼動作,腳色貼圖也就跟著動作,這麼簡單就大功告成了!?
真是大錯特錯 (大錯特錯~不要來~)
◎肢體位置的對應
首先,以成人的比例而言,骨架的相對位置大多都是固定。
但腳色的四肢位置與比例,卻會因為設計或腳色本質的關係,而不可能每次都能與User對應。
以下圖的喵喵為例,若是以腳色head → User head還沒問題,
但腳色hand → User hand,那腳色不就變成手跟身體分家啦,
所以這個方式根本不可行。
◎肢體的角度極限
上圖中,可以看到User左手略為舉高,喵喵的左手也跟著平舉。
但右手已經舉到與頭同高,但腳色的手也無法跟著舉到對應的角度&高度!?
其實仔細觀察&思考,可以發現:
1. 標記圓圈的地方已經露餡啦! (設計時沒有考慮到手臂旋轉的細節)
2. 人體關節可以自然呈現移動的角度非常大(廢話),但2D腳色可不是這樣,
尤其是像這樣的2頭身腳色。(3D不熟無法評論,不過若是3D真人比例的模組來說,
曾看過範例是可以做到的,只是不知如何實作)。
如果沒有繪製對應的角度素材,硬是要讓腳色手臂旋轉角度跟User一樣,
就會變成非常詭異的畫面.....(整隻手幾乎快跟身體分離,只剩一個點)
因此這個互動方式的要點在於
◎必須先設定 & 限制腳色的活動姿勢
◎承上,美術與程式討論後設計對應的素材
◎如果腳色的再用性不高,是否有必要為其特地coding & design?
在這個範例中實現了搖頭、擺手。
手部移動的原理是基於shoulder水平線 & hand的位置去計算夾角,
再轉換成元件可旋轉的角度。
喵喵搖頭的原理與上述類似,以 torso 為基準點,計算head的傾斜角度。
(不使用neck是因為也會移動,這樣就不準確了,只有軀幹是不可能亂旋轉的嘛)
像真人一樣帶動唱跳歌跳舞,看來不太可行。
儘管如此,還是能夠實現讓2D腳色可以隨著User作一些簡單運動。
若對象是小鬼們操控著自己喜愛的動漫腳色,
也能高興好一會兒吧!!
影片請點我
Before Start
Kinect1 vs Kinect2
如上圖,Kinect有2種類型,這裡使用的是第一代Kinect,對應的SDK版本是1.8。
若使用的硬體是Kinect 2,那麼就下載 Kinect for Windows SDK 2.0。
規定要 Win8以上才能使用,不然就會出現以下畫面....
使用AIRKinect開發,網路上已經有很多前輩分享的資訊可以參考,在此感謝。
韩 Hanleon - AIRKinect Tutorial
Gray Liao - AIRKinect
林克融 - 使用FlashDevelop與AirKinect 2.X開發Kinect應用程式
鴨道比 - [教學] AIRKinect 2.0 安裝
Alex - AIRKinect
另外,使用原生開發的 Heresy 也有相當豐富的資料。
照著連結下載SDK、ANE、設定開發環境,
跟著airkinect-2-examples的範例做,很快就可以發現有哪些功能可以玩玩,
不過如果只是照個範例依樣畫葫蘆就沒那麼有趣了,
AirKinect 正是要發揮Flash強大的互動能力才有意思呀!
For example:UserMask、Gesture、Skeleton、AR、with Arduino......
UserMask
一開始想到的方式是直接採用Starling Particle Effect套用在UserMask上,
Particle System只有在建構式的時候才能指定Texture,
我嘗試想要把UserMask.Bitmap放在EnterFrame中,
讓UserMask更新時同時指定給PDParticleSystem 建構式的texture參數,
可惜失敗了 ,看訊息是超過Texture所能承載的限制。
Error: Error #3691: Resource limit for this resource type exceeded.
只有靜止沒更新的BitmapData搭配PDParticleSystem 沒問題,
雖是學藝不精,但也花了太多時間在測試上只能喊停停損。
好吧,那麼退而求其次採用flash native effect
在網路上找到兩個特效範例 (搭配影片服用)
Electric: (程式碼由網友分享,出處已不可考。)
由於UserMask的特性是會不停變更 Bitmap.bitmapdata,
因此調整了一下原本的程式碼,讓UserMask套用效果時(onEnterFrame),
必須將其變更的內容不斷重繪,這麼一來當User影像變更時,
不管採取甚麼姿勢,都可以看到影像周圍都有電流特效。
也可以看到FPS不甚理想(都已經是桌機了怎麼還....=_=),
原來是因為效果是建立於不斷地重繪濾鏡,這吃效能的小怪獸身上。
Fire:(source)
出處來自人稱GS大神製作的火焰特效,
搭配組件使用,調整參數,完全不用coding,效能維持不墜,
(組件MC的圖層要在target上方)
讓你第一次當驚奇四超人的霹靂火就上手! (咦)
FireEffect 同樣是基於不斷變更的UserMask.bitmap而隨之變化,在畫面中可以發現,當User移動時效果會有略為延遲,
因而露出底下的UserMask,這也是運用時要稍微留意之處。
影片請看我