OpenNI简介
OpenNI (开放自然交互)是一个多语言,跨平台的框架,利用符合OpenNI标准的API进行编程,可以使我们与传感器和中间层的具体实现细节相脱离,同时OpenNI也允许我们获取和控制传感器层的数据。
OpenNI的中间件层是实现人体姿态的算法层,目前PrimeSense的NITE(Nature Interacte tecnoligy for End-User)提供了OpenNI标准规定的部分算法。
OpenNI使用分类器的设计概念,把传感器采集的数据逐层向上处理,产生更有用的数据。举例来说传感器采集的 原始数据---经过DepthGenerator-->产生DepthMap--经过GestureGenerator-->产生手势。
详细概念参考OpenNI文档。
程序简介
通过跟踪人的右手平移动作来控制下图中3D立方体的左右旋转。图中比较难看的小人用于显示被跟踪的人头,肩膀,肘和手的位置。程序只跟踪一个人,因为要显示多个人有点麻烦,跟踪一个更能直观的验证OpenNI各API的用法。
用法: 程序启动后,摆出Psi姿势,也就是图中小人的姿势:双手举起(缴枪投降的姿势),当图中的小人开始动时,说明已经被传感器跟踪了, 然后把右手伸出一定距离左右移动来控制立方体的左右旋转。功能比较简单,不过还是挺有意思的,有3D传感器的童鞋可以试试。
运行要求:
3D传感器(PrimeSense或Kinect)
OpenNI SDK
VS2010
代码说明
源代码在我空间里,点击下载
源代码中一个比较重要的类是UserTracker, 它封装了OpenNI的UserGenerator, 通过调用UserGenerator的SkeletonCapability的接口来跟踪人员,当有人进入传感器的可视区域后,开始寻找控制者--检测他是否摆出Psi姿势(可以换成其他的手势,不过这个调用起来比较方便。)。
void userGenerator_NewUser(object sender, NewUserEventArgs e)
{
UserInfo user = new UserInfo() { ID = e.ID };
userDict.Add(e.ID, user);
//userGenerator.SkeletonCapability.StartTracking(e.ID);
if(currentUser == -1)
poseCap.StartPoseDetection("Psi", e.ID);
}
当检测到被跟踪者摆出Psi姿势后,强制对他的骨骼进行校准。
void poseCap_PoseDetected(object sender, PoseDetectedEventArgs e)
{
poseCap.StopPoseDetection(e.ID);
if (currentUser == -1)
{
currentUser = e.ID;
skeletonCap.RequestCalibration(e.ID, true);
}
}
校准成功后,开始跟踪该对象,并把他的骨骼位置信息发送给所有的观察者。
void SkeletonCapability_CalibrationComplete(object sender, CalibrationProgressEventArgs e)
{
if (e.Status == CalibrationStatus.OK)
{
skeletonCap.StartTracking(e.ID);
}
else
{
poseCap.StartPoseDetection("Psi", e.ID);
}
}
private void SkeletonThreadFunc()
{
while (bRunning)
{
try
{
context.WaitAndUpdateAll();
}
catch (Exception)
{
}
int[] userIDs = userGenerator.GetUsers();
foreach (int i in userIDs)
{
if (skeletonCap.IsTracking(i) && i == currentUser)
{
UpdateUser(i);
}
}
}
}
主窗口的代码比较简单,就是接受UserTracker的位置信息,然后调整几个图形的位置,如果发现右手伸出一定距离,并开始左右移动,根据手的移动量进行旋转立方体。