我必须创建一个交互式菜单板。我正在使用 Kinect for Windows SDK v1.8 。直到现在使用其内置的示例项目(控制基础 - Wpf)我能够导航(控制 kinecttilebutton)。当我开始运行程序并且没有人在房间时它完美地工作但是如果在kinect传感器前面有多个人,那么手(Kinect鼠标指针)就会移动到那里。 现在我的问题了 kinect传感器是否只检测特定区域的人(例如x = 100-150,y = 100-150,z = 100-150)?
修改
以下是处理骨架数据的代码。
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
// Even though we un-register all our event handlers when the sensor
// changes, there may still be an event for the old sensor in the queue
// due to the way the KinectSensor delivers events. So check again here.
if (this.KinectSensor != sender)
{
return;
}
using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame())
{
if (null != skeletonFrame)
{
try
{
// Copy the skeleton data from the frame to an array used for temporary storage
skeletonFrame.CopySkeletonDataTo(this.skeletons);
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
// Hand data to Interaction framework to be processed
this.interactionStream.ProcessSkeleton(this.skeletons, accelerometerReading, skeletonFrame.Timestamp);
}
catch (InvalidOperationException)
{
// SkeletonFrame functions may throw when the sensor gets
// into a bad state. Ignore the frame in that case.
}
}
}
}
答案 0 :(得分:1)
我遇到了同样的问题通过使用下面的代码我只跟踪了一个更接近传感器的骨架。并直接将最接近的骨架分配给主骨架流。
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame())
{
if (skeletonFrame != null && this.skeletons != null)
{
//Console.WriteLine(skeletonFrame.SkeletonArrayLength);
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
// Set skeleton datas from skeletonFrame
skeletonFrame.CopySkeletonDataTo(this.skeletons);
TrackClosestSkeleton();
Skeleton[] singleSkeleton = new Skeleton[6];
Skeleton skl=(from mno in this.skeletons where mno.TrackingState==SkeletonTrackingState.Tracked && mno.TrackingId==globalClosestID select mno).FirstOrDefault();
if (skl == null)
return;
//Creating an empty skkeleton
Skeleton emptySkeleton = new Skeleton();
singleSkeleton[0] = skl; //Pass the Tracked skeleton with closestID
singleSkeleton[1] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[2] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[3] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[4] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[5] = emptySkeleton; //Passing Empty Skeleton
this.snew.SkeletonStream.ChooseSkeletons(globalClosestID);
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
this.interactionStream.ProcessSkeleton(singleSkeleton, accelerometerReading, skeletonFrame.Timestamp);
}
}
}
int globalClosestID = 0;
private void TrackClosestSkeleton()
{
if (this.snew != null && this.snew.SkeletonStream != null)
{
if (!this.snew.SkeletonStream.AppChoosesSkeletons)
{
this.snew.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
}
float closestDistance = 10000f; // Start with a far enough distance
int closestID = 0;
foreach (Skeleton skeleton in this.skeletons.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skeleton.Position.Z < closestDistance)
{
closestID = skeleton.TrackingId;
closestDistance = skeleton.Position.Z;
}
}
if (closestID > 0)
{
this.snew.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
globalClosestID = closestID;
}
}
}
检查上面的代码对我有用。它可能对你有帮助。重新认识的是Kinectsensor。
答案 1 :(得分:0)
最简单的解决方案是跟踪最近的骨架。
private void TrackClosestSkeleton()
{
if (this.kinect != null && this.kinect.SkeletonStream != null)
{
if (!this.kinect.SkeletonStream.AppChoosesSkeletons)
{
this.kinect.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
}
float closestDistance = 10000f; // Start with a far enough distance
int closestID = 0;
foreach (Skeleton skeleton in this.skeletonData.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skeleton.Position.Z < closestDistance)
{
closestID = skeleton.TrackingId;
closestDistance = skeleton.Position.Z;
}
}
if (closestID > 0)
{
this.kinect.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
}
}
}
获取参考here
像这样使用:
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
// Even though we un-register all our event handlers when the sensor
// changes, there may still be an event for the old sensor in the queue
// due to the way the KinectSensor delivers events. So check again here.
if (this.KinectSensor != sender)
{
return;
}
using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame())
{
if (null != skeletonFrame)
{
try
{
// Copy the skeleton data from the frame to an array used for temporary storage
skeletonFrame.CopySkeletonDataTo(this.skeletons);
TrackClosesSkeleton();
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
// Hand data to Interaction framework to be processed
this.interactionStream.ProcessSkeleton(this.skeletons, accelerometerReading, skeletonFrame.Timestamp);
}
catch (InvalidOperationException)
{
// SkeletonFrame functions may throw when the sensor gets
// into a bad state. Ignore the frame in that case.
}
}
}
}
这只是一个快速编辑,所以也许您可能会重命名一些变量以使其适合