Kinect的横盘骨架追踪 [英] Kinect sideways skeleton tracking
问题描述
目前我使用的是微软Kinect的关节之间测量角度。大多数测量工作是否正常。每当一个人侧身坐(在椅子)Kinect的不会跟踪骨架准确。为了说明我的问题,我已经添加了Kinect的depthview的3张照片。
Currently I am using the Microsoft Kinect for measuring angles between joints. Most measurements are working correctly. Whenever a person is sitting sideways (on a chair) the Kinect won't track the skeleton accurate. To illustrate my problem I've added 3 pictures of the Kinect depthview.
正如你所看到的3取2的测量工作正常。每当我抬起我的腿,Kinect的正确停止骨架跟踪。有没有人有一个解决这个问题,或者这只是Kinect的?
As you can see 2 out of 3 measurements work "correctly". Whenever I lift my leg, the Kinect stops skeleton tracking correctly. Does anyone have a solution to this problem, or is this just a limitation of the Kinect?
感谢。
更新1:
在 JointTrackingState的枚举
上截图2所示,这些跟踪的关节都被标记为推断
,但是深入了解被跟踪我全身。
Update 1:
The JointTrackingState-Enumeration
on these tracked joints shown at screenshot 2 are marked as Inferred
, however the depth view is tracking my full body.
更新2:
在截图2我想跟踪我的前腿,突出绿色。我知道,另一条腿不跟踪,但是这并不重要,我猜。
Update 2: At screenshot 2 I'm trying to track my front leg, highlighted as green. I know the other leg isn't tracked but this does not matter, I guess.
更新3:
下面code选择一个模板:
Update 3: The following code selects a skeleton:
private Skeleton StickySkeleton(Skeleton[] skeletons)
{
if (skeletons.Count<Skeleton>(skeleton => skeleton.TrackingId == _trackedSkeletonId) <= 0)
{
_trackedSkeletonId = -1;
_skeleton = null;
}
if (_trackedSkeletonId == -1)
{
Skeleton foundSkeleton = skeletons.FirstOrDefault<Skeleton>(skeleton => skeleton.TrackingState == SkeletonTrackingState.Tracked);
if (foundSkeleton != null)
{
_trackedSkeletonId = foundSkeleton.TrackingId;
return foundSkeleton;
}
}
return _skeleton;
}
每当骨架跟踪该数据将被用于绘制关节点和计算关节之间的角度
Whenever a skeleton is tracked that data will be used for drawing the joint-points and calculating the angle between joints.
更新4:
我测试过坐在块上,远远高于椅子更加简化。不幸的是,Kinect的动作仍然相同。
Update 4: I've tested sitting on a 'block', far more simplified than a chair. Unfortunately the Kinect still acts the same.
2下面的截图:
推荐答案
由于雷诺杜蒙说,我会做 JointTrackingState
的东西。由于您使用的膝盖,我使用的变量 leftknee
和 rightknee
这是接头
来做到这一点。这里是code,你可以使用 JointType.FootRight
和 JointType.FootLeft
和髋
的类型,但我会离开,你。
As Renaud Dumont stated, I would do something with JointTrackingState
. Since your using knees, I used the variables leftknee
and rightknee
which are Joints
to do it. Here's code, You might use JointType.FootRight
and JointType.FootLeft
and the Hip
types, but I'll leave that up to you.
static Skeleton first = new Skeleton();
Joint leftknee = first.Joints[JointType.KneeLeft];
Joint rightknee = first.Joints[JointType.KneeRight];
if ((leftknee.TrackingState == JointTrackingState.Inferred ||
leftknee.TrackingState == JointTrackingState.Tracked) &&
(rightknee.TrackingState == JointTrackingState.Tracked ||
rightknee.TrackingState == JointTrackingState.Inferred))
{
}
或者交替,如果你只是想单膝同时进行跟踪,或两者兼而有之,你可以这样做:
Or alternately, if you just wanted one knee to be tracked at a time, or both, you could do this:
if ((leftknee.TrackingState == JointTrackingState.Inferred ||
leftknee.TrackingState == JointTrackingState.Tracked) &&
(rightknee.TrackingState == JointTrackingState.Tracked ||
rightknee.TrackingState == JointTrackingState.Inferred))
{
}
else if (leftknee.TrackingState == JointTrackingState.Inferred ||
leftknee.TrackingState == JointTrackingState.Tracked)
{
}
else if (rightknee.TrackingState == JointTrackingState.Inferred ||
rightknee.TrackingState == JointTrackingState.Tracked)
{
}
FYI的原因骨架
是第一
是静态
是因为那可以在使关节使用
FYI the reason the Skeleton
is first
is static
is because then it can be used in making the joints
static Skeleton first;
被反对
Skeleton first;
编辑1
我得出的结论是这个极其很难做到的,我觉得上面的方法将工作,但我只是想包括什么,我的情况下工作,你也许能找到一些办法让它工作。反正这里的code我工作的这是另一个
类
这是另一个 SkeletalTrackingState
我试着它使一个推断
枚举
。但不幸的是枚举
来继承
。如果你找到这个效果的作品,我会尊重你作为一个卓越的程序员我一辈子)。事不宜迟:本的.dll
我试图让:
Edit 1
I've come to the conclusion this is extremely difficult to do, I think the above method will work, but I just wanted to include what I'm working on in case you might be able to find some way to make it work. Anyways Here's the code I was working on which is another
class
which is just another SkeletalTrackingState
I was trying to make an Inferred
enum
in it. But unfortunately enum
are impossible to inherit
. If you find something to this effect that works, I will respect you as a superior programmer to me forever ;). Without further ado: The .dll
I was trying to make:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;
namespace IsInferred
{
public abstract class SkeletonInferred : Skeleton
{
public bool inferred;
static Skeleton first1 = new Skeleton();
Joint handright;
Joint handleft;
Joint footright;
Joint footleft;
Joint ankleleft;
Joint ankleright;
Joint elbowleft;
Joint elbowright;
Joint head;
Joint hipcenter;
Joint hipleft;
Joint hipright;
Joint shouldercenter;
Joint shoulderleft;
Joint shoulderright;
Joint kneeleft;
Joint kneeright;
Joint spine;
Joint wristleft;
Joint wristright;
public SkeletonInferred(bool inferred)
{
}
public enum Inferred
{
NotTracked = SkeletonTrackingState.NotTracked,
PositionOnly = SkeletonTrackingState.PositionOnly,
Tracked = SkeletonTrackingState.Tracked,
Inferred = 3,
}
private void IsInferred(object sender, AllFramesReadyEventArgs e)
{
handright = first1.Joints[JointType.HandRight];
handleft = first1.Joints[JointType.HandLeft];
footright = first1.Joints[JointType.FootRight];
footleft = first1.Joints[JointType.FootLeft];
ankleleft = first1.Joints[JointType.AnkleLeft];
ankleright = first1.Joints[JointType.AnkleRight];
elbowleft = first1.Joints[JointType.ElbowLeft];
elbowright = first1.Joints[JointType.ElbowRight];
head = first1.Joints[JointType.Head];
hipcenter = first1.Joints[JointType.HipCenter];
hipleft = first1.Joints[JointType.HipLeft];
hipright = first1.Joints[JointType.HipRight];
shouldercenter = first1.Joints[JointType.ShoulderCenter];
shoulderleft = first1.Joints[JointType.ShoulderLeft];
shoulderright = first1.Joints[JointType.ShoulderRight];
kneeleft = first1.Joints[JointType.KneeLeft];
kneeright = first1.Joints[JointType.KneeRight];
spine = first1.Joints[JointType.Spine];
wristleft = first1.Joints[JointType.WristLeft];
wristright = first1.Joints[JointType.WristRight];
if (handleft.TrackingState == JointTrackingState.Inferred &
handright.TrackingState == JointTrackingState.Inferred &
head.TrackingState == JointTrackingState.Inferred &
footleft.TrackingState == JointTrackingState.Inferred &
footright.TrackingState == JointTrackingState.Inferred &
ankleleft.TrackingState == JointTrackingState.Inferred &
ankleright.TrackingState == JointTrackingState.Inferred &
elbowleft.TrackingState == JointTrackingState.Inferred &
elbowright.TrackingState == JointTrackingState.Inferred &
hipcenter.TrackingState == JointTrackingState.Inferred &
hipleft.TrackingState == JointTrackingState.Inferred &
hipright.TrackingState == JointTrackingState.Inferred &
shouldercenter.TrackingState == JointTrackingState.Inferred &
shoulderleft.TrackingState == JointTrackingState.Inferred &
shoulderright.TrackingState == JointTrackingState.Inferred &
kneeleft.TrackingState == JointTrackingState.Inferred &
kneeright.TrackingState == JointTrackingState.Inferred &
spine.TrackingState == JointTrackingState.Inferred &
wristleft.TrackingState == JointTrackingState.Inferred &
wristright.TrackingState == JointTrackingState.Inferred)
{
inferred = true;
}
}
}
}
在code在您的项目(编译错误)
The code in your project (compiler error)
using IsInferred;
static bool Inferred = false;
SkeletonInferred inferred = new SkeletonInferred(Inferred);
static Skeleton first1 = new Skeleton();
Skeleton foundSkeleton = skeletons.FirstOrDefault<Skeleton>(skeleton => skeleton.TrackingState == SkeletonTrackingState.Inferred);
祝你好运,我希望这可以帮助你在正确的方向前进,或帮助你了!
Good luck, I hope this helps you get going in the right direction or helps you at all!
这里是我的code,你提出的要求。是的,它是从骨骼跟踪基本面,但这code在这里,我没'T想入手大多数相同的东西,一个新的项目。请享用!
Here's my code that you asked for. Yes it is from the Skeletal Tracking Fundamentals, but this code was here and I didn't want to start a new project with most of the same stuff. Enjoy!
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
using Coding4Fun.Kinect.Wpf;
namespace SkeletalTracking
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
bool closing = false;
const int skeletonCount = 6;
Skeleton[] allSkeletons = new Skeleton[skeletonCount];
private void Window_Loaded(object sender, RoutedEventArgs e)
{
kinectSensorChooser1.KinectSensorChanged += new DependencyPropertyChangedEventHandler(kinectSensorChooser1_KinectSensorChanged);
}
void kinectSensorChooser1_KinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
{
KinectSensor old = (KinectSensor)e.OldValue;
StopKinect(old);
KinectSensor sensor = (KinectSensor)e.NewValue;
if (sensor == null)
{
return;
}
var parameters = new TransformSmoothParameters
{
Smoothing = 0.3f,
Correction = 0.0f,
Prediction = 0.0f,
JitterRadius = 1.0f,
MaxDeviationRadius = 0.5f
};
sensor.SkeletonStream.Enable(parameters);
//sensor.SkeletonStream.Enable();
sensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(sensor_AllFramesReady);
sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
try
{
sensor.Start();
}
catch (System.IO.IOException)
{
kinectSensorChooser1.AppConflictOccurred();
}
}
void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
if (closing)
{
return;
}
//Get a skeleton
Skeleton first = GetFirstSkeleton(e);
if (first == null)
{
return;
}
//set scaled position
//ScalePosition(headImage, first.Joints[JointType.Head]);
ScalePosition(leftEllipse, first.Joints[JointType.HandLeft]);
ScalePosition(rightEllipse, first.Joints[JointType.HandRight]);
ScalePosition(leftknee, first.Joints[JointType.KneeLeft]);
ScalePosition(rightknee, first.Joints[JointType.KneeRight]);
GetCameraPoint(first, e);
}
void GetCameraPoint(Skeleton first, AllFramesReadyEventArgs e)
{
using (DepthImageFrame depth = e.OpenDepthImageFrame())
{
if (depth == null ||
kinectSensorChooser1.Kinect == null)
{
return;
}
//Map a joint location to a point on the depth map
//head
DepthImagePoint headDepthPoint =
depth.MapFromSkeletonPoint(first.Joints[JointType.Head].Position);
//left hand
DepthImagePoint leftDepthPoint =
depth.MapFromSkeletonPoint(first.Joints[JointType.HandLeft].Position);
//right hand
DepthImagePoint rightDepthPoint =
depth.MapFromSkeletonPoint(first.Joints[JointType.HandRight].Position);
DepthImagePoint rightKnee =
depth.MapFromSkeletonPoint(first.Joints[JointType.KneeRight].Position);
DepthImagePoint leftKnee =
depth.MapFromSkeletonPoint(first.Joints[JointType.KneeLeft].Position);
//Map a depth point to a point on the color image
//head
ColorImagePoint headColorPoint =
depth.MapToColorImagePoint(headDepthPoint.X, headDepthPoint.Y,
ColorImageFormat.RgbResolution640x480Fps30);
//left hand
ColorImagePoint leftColorPoint =
depth.MapToColorImagePoint(leftDepthPoint.X, leftDepthPoint.Y,
ColorImageFormat.RgbResolution640x480Fps30);
//right hand
ColorImagePoint rightColorPoint =
depth.MapToColorImagePoint(rightDepthPoint.X, rightDepthPoint.Y,
ColorImageFormat.RgbResolution640x480Fps30);
ColorImagePoint leftKneeColorPoint =
depth.MapToColorImagePoint(leftKnee.X, leftKnee.Y,
ColorImageFormat.RgbResolution640x480Fps30);
ColorImagePoint rightKneeColorPoint =
depth.MapToColorImagePoint(rightKnee.X, rightKnee.Y,
ColorImageFormat.RgbResolution640x480Fps30);
//Set location
CameraPosition(headImage, headColorPoint);
CameraPosition(leftEllipse, leftColorPoint);
CameraPosition(rightEllipse, rightColorPoint);
Joint LEFTKNEE = first.Joints[JointType.KneeLeft];
Joint RIGHTKNEE = first.Joints[JointType.KneeRight];
if ((LEFTKNEE.TrackingState == JointTrackingState.Inferred ||
LEFTKNEE.TrackingState == JointTrackingState.Tracked) &&
(RIGHTKNEE.TrackingState == JointTrackingState.Tracked ||
RIGHTKNEE.TrackingState == JointTrackingState.Inferred))
{
CameraPosition(rightknee, rightKneeColorPoint);
CameraPosition(leftknee, leftKneeColorPoint);
}
else if (LEFTKNEE.TrackingState == JointTrackingState.Inferred ||
LEFTKNEE.TrackingState == JointTrackingState.Tracked)
{
CameraPosition(leftknee, leftKneeColorPoint);
}
else if (RIGHTKNEE.TrackingState == JointTrackingState.Inferred ||
RIGHTKNEE.TrackingState == JointTrackingState.Tracked)
{
CameraPosition(rightknee, rightKneeColorPoint);
}
}
}
Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e)
{
using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
{
if (skeletonFrameData == null)
{
return null;
}
skeletonFrameData.CopySkeletonDataTo(allSkeletons);
//get the first tracked skeleton
Skeleton first = (from s in allSkeletons
where s.TrackingState == SkeletonTrackingState.Tracked
select s).FirstOrDefault();
return first;
}
}
private void StopKinect(KinectSensor sensor)
{
if (sensor != null)
{
if (sensor.IsRunning)
{
//stop sensor
sensor.Stop();
//stop audio if not null
if (sensor.AudioSource != null)
{
sensor.AudioSource.Stop();
}
}
}
}
private void CameraPosition(FrameworkElement element, ColorImagePoint point)
{
//Divide by 2 for width and height so point is right in the middle
// instead of in top/left corner
Canvas.SetLeft(element, point.X - element.Width / 2);
Canvas.SetTop(element, point.Y - element.Height / 2);
}
private void ScalePosition(FrameworkElement element, Joint joint)
{
//convert the value to X/Y
//Joint scaledJoint = joint.ScaleTo(1280, 720);
//convert & scale (.3 = means 1/3 of joint distance)
Joint scaledJoint = joint.ScaleTo(1280, 720, .3f, .3f);
Canvas.SetLeft(element, scaledJoint.Position.X);
Canvas.SetTop(element, scaledJoint.Position.Y);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
closing = true;
StopKinect(kinectSensorChooser1.Kinect);
}
private void kinectDepthViewer1_Loaded(object sender, RoutedEventArgs e)
{
}
}
}
XAML
<Window x:Class="SkeletalTracking.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="800" Loaded="Window_Loaded"
xmlns:my="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers"
Closing="Window_Closing" WindowState="Maximized">
<Canvas Name="MainCanvas">
<my:KinectColorViewer Canvas.Left="0" Canvas.Top="0" Width="640" Height="480" Name="kinectColorViewer1"
Kinect="{Binding ElementName=kinectSensorChooser1, Path=Kinect}" />
<Ellipse Canvas.Left="0" Canvas.Top="0" Height="50" Name="leftEllipse" Width="50" Fill="#FF4D298D" Opacity="1" Stroke="White" />
<Ellipse Canvas.Left="100" Canvas.Top="0" Fill="#FF2CACE3" Height="50" Name="rightEllipse" Width="50" Opacity="1" Stroke="White" />
<my:KinectSensorChooser Canvas.Left="250" Canvas.Top="380" Name="kinectSensorChooser1" Width="328" />
<Image Canvas.Left="66" Canvas.Top="90" Height="87" Name="headImage" Stretch="Fill" Width="84" Source="/SkeletalTracking;component/c4f-color.png" />
<Ellipse Canvas.Left="283" Canvas.Top="233" Height="23" Name="leftknee" Stroke="Black" Width="29" />
<Ellipse Canvas.Left="232" Canvas.Top="233" Height="23" Name="rightknee" Stroke="Black" Width="30" />
</Canvas>
下面是一个图例,说明如何关闭的Kinect可有时:
提示:请注意如何只有在检测我的胳膊和背景的一部分。
Here's a picture just to show how off Kinect can be sometimes:
Hint: Notice how only my arm is detected and part of the background
这篇关于Kinect的横盘骨架追踪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!