0

楕円を手関節にマッピングしたいのですが、手関節が動くので楕円を動かさなければなりません。

kinectSdk1.5を使用してプログラムを実行するのに役立つリファレンスリンクをいくつか提供してください。ありがとうございました

4

2 に答える 2

3

@Heisenbugは機能しますが、WPFにははるかに簡単な方法があります。チュートリアルは、Channel9のSkeletonFundamentalsにあります。基本的にはキャンバスが必要ですが、必要な楕円はいくつも必要です。これがコード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"  
    Closing="Window_Closing" WindowState="Maximized">       
<Canvas Name="MainCanvas">
    <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" />
    <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>
</Window>

ここでは、4つの楕円(膝、手)と画像(頭)を使用しています。これに不可欠なコードはここにあります:

    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)
        //note you need to have Coding4Fun
        Joint scaledJoint = joint.ScaleTo(1280, 720, .3f, .3f);

        Canvas.SetLeft(element, scaledJoint.Position.X);
        Canvas.SetTop(element, scaledJoint.Position.Y);
    }

これがこのプログラムの鍵です。ジョイントから位置を取得し、要素の位置をそこに変更します。次の部分も重要です。次のようにします。

    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);


            //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);


            //Set location
            CameraPosition(headImage, headColorPoint);
            CameraPosition(leftEllipse, leftColorPoint);
            CameraPosition(rightEllipse, rightColorPoint);
        }
    }

上記のコードは、スケルトンポイントを深度フレームにマップし、次にカラーフレームにマップします。

    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;

        }
    }

これにより、選択するスケルトンのコードが取得されます。次に、AllFrameReadyEventArgsこれを実行してすべてをまとめます。

    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);
    }

後ろにカラー画像があると結果は最高に見えますが、今はその部分をスキップすることにしました。お役に立てれば!

于 2012-08-07T14:02:22.310 に答える
2

基本的に、コードのどこかに、KinectSDKと対話するためのクラスがあります。

private KinectSensor kinectSensor;

この方法でKinectSensorを初期化できます。

public void kinectInit()
{
    KinectSensor.KinectSensors.StatusChanged += (object sender, StatusChangedEventArgs e) =>
    {
        if (e.Sensor == kinectSensor)
        {
            if (e.Status != KinectStatus.Connected)
            {
                SetSensor(null);
            }
        }else if ((kinectSensor == null) && (e.Status == KinectStatus.Connected))
        {
            SetSensor(e.Sensor);
        }
    };

    foreach (var sensor in KinectSensor.KinectSensors)
    {
        if (sensor.Status == KinectStatus.Connected)
        {
            SetSensor(sensor);
         }
    }
}

基本的に、変更されたKinectSensorのステータスを処理するためのデリゲートを定義しています。SetSensorメソッドは次のようになります。

private void SetSensor(KinectSensor newSensor)
{
    if (kinectSensor != null)
    {
        kinectSensor.Stop();
    }

    kinectSensor = newSensor;

    if (kinectSensor != null)
    {
        kinectSensor.SkeletonStream.Enable();
        kinectSensor.SkeletonFrameReady += OnSkeletonFrameReady;
        kinectSensor.Start();
     }
}

さて、OnSkeletonFrameReadyは「更新関数」です。これは、Kinectセンサーが更新されるたびに継続的に呼び出されます。その中から、ジョイントに関する情報を取得して、必要なものをレンダリングできます。

private void OnSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{

    skelFrame = e.OpenSkeletonFrame();
    skeletons = new Skeleton[kinectSensor.SkeletonStream.FrameSkeletonArrayLength];          

    if (skelFrame != null)
    {
        skelFrame.CopySkeletonDataTo(skeletons);
        foreach (Skeleton skel in skeletons) {
        if (skel.TrackingState >= SkeletonTrackingState.Tracked)
        {
            //here's get the joints for each tracked skeleton
            SkeletonPoint rightHand = skel.Joints[JointType.HandRight].Position;
            ....    
         }
    }
}

C#とKinectを使用しているため、楕円のレンダリングに使用できる単純なライブラリはXNAです。

于 2012-08-07T11:29:52.353 に答える