OpenNI 人體骨架分析部分補充


這一篇主要是針對《透過 OpenNI / NITE 分析人體骨架(上)》和《透過 OpenNI / NITE 分析人體骨架(下)》這兩篇文章,做一些簡單的資料補充。由於這算是比較簡單的筆記,所以就簡單寫一下,不附上完整的程式碼了。

關節位置的平滑化

實際上,OpenNI 所讀出來的深度資料有一定的誤差、甚至每個點的值在李英固定的情況下,也會有相當程度的變動。而同樣的情況,也發生在透過 xn::SkeletonCapability 讀取到的關節位置上;也就是說,讀取到的關節位置,會有一定程度的抖動的現象。

而要怎樣減輕這樣的問題呢?OpenNI 在 xn::SkeletonCapability 這個 capability 裡有提供一個名為 SetSmoothing() 的函式,可以傳入一個浮點樹當作調整參數、來針對讀取到的結果作平滑化;他的值的範圍應該是 0 到 1 之間,越大的話得到的結果連續下來會越平滑,不過相對的也會喪失細節、並且增加一些時間上的延遲。

所以,基本上這部分可能是要視需求去做參數的調整。而理論上,只要在初始化階段透過 SetSmoothing() 這個函式設定好平滑化的參數後,就可以減輕關節資料抖動的現象了。

使用現有的校正資料(不用再擺出校正姿勢)

在使用 OpenNI 做人體姿勢分析的時候,標準的作法是需要擺出 NITE 的標準校正姿勢、也就是所謂的 PSI 姿勢的。不過說實話,要使用者都得擺出這個姿勢一小段時間後、才能開始使用,其實算是滿麻煩的。而實際上 OpenNI 是有提供骨架校正資料的儲存取存取,某種程度上是可以用來做到「不用先擺校正姿勢的人體骨架分析」的!

以目前的 OpenNI 來說,它提供了兩組(四個)相關的函式,可供利用。這兩組函式分別為:

  • 儲存、讀取記憶體裡的校正資料
    • XnStatus SaveCalibrationData( XnUserID user, XnUInt32 nSlot )
    • XnStatus LoadCalibrationData( XnUserID user, XnUInt32 nSlot )
  • 儲存、讀取檔案形式的校正資料
    • XnStatus SaveCalibrationDataToFile( XnUserID user, const XnChar *strFileName )
    • XnStatus LoadCalibrationDataFromFile( XnUserID user, const XnChar *strFileName )

第一組的函式,是可以將已經特定使用者(根據 user ID)校正好的骨架資料,透過 SaveCalibrationData() 儲存到記憶體裡指定的 slot 中(用整數來代表 slot 編號),之後再透過 LoadCalibrationData() 讀出來、套用指定的使用者上使用。

而第二組的函式基本上也是類似的,不過他是將骨架的校正資料以檔案的形式來做儲存與讀取;如此一來,就算程式已經結束過、要重新執行,也還是可以重複利用這些校正過的資料。

要使用這兩組函式其實也不複雜。儲存的部分,主要就是要等到使用者已經完成骨架的校正後(就是《透過 OpenNI / NITE 分析人體骨架(上)》中的 CalibrationEnd() 裡),透過 SaveCalibrationData()SaveCalibrationDataToFile() 來將校正好的資料儲存下來。

而之後要套用儲存下來的骨架校正資料的話,則是要 user generator 有抓到新的使用者、建立新的 user 後(就是《透過 OpenNI / NITE 分析人體骨架(上)》中的 NewUser() 裡),透過 LoadCalibrationData()LoadCalibrationDataFromFile(),直接將儲存好的骨架校正資料讀取出來、並直接套用在新的 user 上(透過指定 user ID)。如此一來,OpenNI 就會認為這個 user 已經經過骨架校正的步驟了~也就是說,可以不用再擺出指定的校正姿勢(PSI),就可以直接開始追蹤骨架了~

而這樣的功能比較直接的應用,應該就是先儲存好一組校正的結果資料,然後之後對於所有新偵測到的使用者,都直接套用這一組骨架校正資料了!這樣基本上,就算是做到「不用擺出校正姿勢的人體骨架分析與追蹤」了~而實際測試的話,這個方法在某種程度上應該算是可行的~

不過,在 Heresy 來看,透過指定姿勢(PSI)來進行骨架的校正實際上應該還是有其必要性的;而這樣的作法,算是把一組校正好的骨架資料當作標準範例、硬套用到所有其他 user generator 偵測到的「使用者上」,所以還是會有可能有問題的。像 Heresy 在實際測試的時候,不但有可能會導致某些非人的物體,也被硬套上骨架的情形,而即使是人,在某些狀況下,也會有骨架資料沒辦法正確追蹤的狀況。整體來說,Heresy 是覺得這種強制套用校正資料的方法,穩定性是相對比較差的。

目前沒有繼續再玩下去,不過 Heresy 現在的想法,是覺得應該可以透過骨架各關節的可靠度,來判斷這種強制套用的結果是否合適,如此或許可以略過某些不合適的例子;但是實際上這也還只是個想法,並沒有經過實測就是了。


OpenNI / Kinect 相關文章目錄

對「OpenNI 人體骨架分析部分補充」的想法

  1. 您好目前我是使用《透過 OpenNI / NITE 分析人體骨架(上)》來抓取全身坐標之中右手的座標

    可是如大大所說會有嚴重的抖動情況

    假如想要平滑可以直接改其中的code還是需要做甚麼修正?

    大概加甚麼東西在哪個部分

    • 不好意思比較沒基礎再麻煩您清楚一點點出將SetSmoothing() 或者甚麼方法放在哪一段

    • SetSmoothing() 是控制用的參數,基本上只要把相關的物件建立出來後,就可以呼叫了,沒有限制要放在哪。

        • 以這邊來說,SetSmoothing() 是 xn::SkeletonCapability 的函式,所以你至少得要可以取得 xn::SkeletonCapability 才能呼叫。
          也因此,你必須要先把 UserGenerator 建立好才可以用。

          • // 3. create depth generator
            xn::DepthGenerator mDepthGenerator;
            xn::SkeletonCapability SetSmoothing();
            mDepthGenerator.Create( mContext );
            mDepthGenerator.SetMapOutputMode( mapMode );

            我放在這邊對嗎? 請問有需要再()加上參數?

          • XN_C_API XnStatus XN_C_DECL xnSetSkeletonSmoothing ( XnNodeHandle hInstance,
            XnFloat fFactor
            )

            這?…不太懂

          • 你這邊的程式碼基本上應該是不合法的語法,應 該不可能編譯過的。

            建議請參考這篇的範例來做修改
            https://kheresy.wordpress.com/2011/12/06/nite1-5_skeleton_without_calibration_pose/
            https://kheresy.wordpress.com/2011/01/28/detecte_skeleton_via_openni_part1/

            裡面就有使用到 SkeletonCapability 的東西。

            而且,文章和之前的回應也都已經有說明了,SkeletonCapability 是由 UserGenerator 提供的,你的程式應該要加在 UserGenerator 建立好之後。
            但是你這邊是加上 DepthGenerator 的建立?

          • // 8. start generate data
            mContext.StartGeneratingAll();
            mSC.SetSmoothing(0.1);

            我是直接套用您在https://kheresy.wordpress.com/2011/01/28/detecte_skeleton_via_openni_part1/

            的文章code 所以UserGenerator 建立已經完成?

            編譯出來可執行可是我不確定他真的有smoothing 這樣有完成?

          • 文章內已經有說明了,
            他的值的範圍應該是 0 到 1 之間,越大的話得到的結果連續下來會越平滑,不過相對的也會喪失細節、並且增加一些時間上的延遲

          • 不好意思我可能描述得不好

            我的意思是0.1~1的1是指過濾掉1mm的雜訊? 還是甚麼嗎?

發表留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料