Friday, October 23, 2015

การวาด Skeleton จาก Kinect ตอนที่ 2: วาดทั้งตัว

เมื่อรู้ตำแหน่งของข้อต่อแล้ว เราสามารถวาดโครงกระดูกทั้งตัวโดยใช้ลากเส้นตรงเชื่อมข้อต่อเข้าด้วยกัน ซึ่งข้อต่อต่างๆที่ Kinect จับได้มีดังนี้

ที่มาของรูป https://msdn.microsoft.com/en-us/library/jj131025.aspx

เพื่อให้สะดวก เราจะเขียนฟังก์ชันการวาดรูปแยกออกมาต่างหาก แล้วส่งข้อต่อต่างๆไปให้ฟังก์ชันนี้วาด พอวาดเสร็จเฟรมนึงก็ลบทิ้งแล้ววาดใหม่

ผลลัพธ์ที่ได้เมื่อ Kinect ตรวจจับคนได้



โค้ดก็จะมีเพิ่มเติมมาในส่วนของฟังก์ชัน และการเรียกใช้ฟังก์ชันนี้เพื่อวาดเส้นตรงระหว่างข้อต่อต่างๆ ดังนี้ครับ

โค้ด UI
<Window x:Class="SkeletonFull.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Skeleton Tracking" SizeToContent="WidthAndHeight" Loaded="Window_Loaded">
    <Canvas Name="skeletonCanvas" HorizontalAlignment="Center" Height="480" Width="640"/>
</Window>

โค้ด C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;

namespace SkeletonFull
{
    public partial class MainWindow : Window
    {
        KinectSensor myKinect;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Check to see if a Kinect is available
            if (KinectSensor.KinectSensors.Count == 0)
            {
                MessageBox.Show("No Kinects detected", "Camera Viewer");
                Application.Current.Shutdown();
            }

            // Get the first Kinect on the computer
            myKinect = KinectSensor.KinectSensors[0];

            // Start the Kinect running and select the depth camera
            try
            {
                myKinect.SkeletonStream.Enable();
                myKinect.Start();
            }
            catch
            {
                MessageBox.Show("Kinect initialise failed", "Camera Viewer");
                Application.Current.Shutdown();
            }

            // connect a handler to the event that fires when new frames are available
            myKinect.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(myKinect_SkeletonFrameReady);
        }

        //drawing color
        Brush brushColor = new SolidColorBrush(Colors.Red);
        //method to draw a line between joints
        void drawLine(Joint j1, Joint j2)
        {
            Line bone = new Line();
            //drawing color and thickness
            bone.Stroke = brushColor;
            bone.StrokeThickness = 5;

            //map joint position to display location
            //starting point
            ColorImagePoint j1p = myKinect.CoordinateMapper.MapSkeletonPointToColorPoint(j1.Position, ColorImageFormat.RgbResolution640x480Fps30);
            bone.X1 = j1p.X;
            bone.Y1 = j1p.Y;
            //ending point
            ColorImagePoint j2p = myKinect.CoordinateMapper.MapSkeletonPointToColorPoint(j2.Position, ColorImageFormat.RgbResolution640x480Fps30);
            bone.X2 = j2p.X;
            bone.Y2 = j2p.Y;

            //add line to canvas
            skeletonCanvas.Children.Add(bone);
        }

        private void myKinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            // Remove the old skeleton
            skeletonCanvas.Children.Clear();

            Skeleton[] skeletons = null;

            using (SkeletonFrame frame = e.OpenSkeletonFrame())
            {
                if (frame != null)
                {
                    skeletons = new Skeleton[frame.SkeletonArrayLength];
                    frame.CopySkeletonDataTo(skeletons);
                }
            }

            if (skeletons == null) 
                return;

            foreach (Skeleton skeleton in skeletons)
            {
                if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
                {
                    //draw head to neck
                    drawLine(skeleton.Joints[JointType.Head], skeleton.Joints[JointType.ShoulderCenter]);
                    //draw neck to spine
                    drawLine(skeleton.Joints[JointType.ShoulderCenter], skeleton.Joints[JointType.Spine]);
                    //draw spine to hip center
                    drawLine(skeleton.Joints[JointType.Spine], skeleton.Joints[JointType.HipCenter]);

                    //draw left arm
                    drawLine(skeleton.Joints[JointType.ShoulderCenter], skeleton.Joints[JointType.ShoulderLeft]);
                    drawLine(skeleton.Joints[JointType.ShoulderLeft], skeleton.Joints[JointType.ElbowLeft]);
                    drawLine(skeleton.Joints[JointType.ElbowLeft], skeleton.Joints[JointType.WristLeft]);
                    drawLine(skeleton.Joints[JointType.WristLeft], skeleton.Joints[JointType.HandLeft]);

                    //draw right arm
                    drawLine(skeleton.Joints[JointType.ShoulderCenter], skeleton.Joints[JointType.ShoulderRight]);
                    drawLine(skeleton.Joints[JointType.ShoulderRight], skeleton.Joints[JointType.ElbowRight]);
                    drawLine(skeleton.Joints[JointType.ElbowRight], skeleton.Joints[JointType.WristRight]);
                    drawLine(skeleton.Joints[JointType.WristRight], skeleton.Joints[JointType.HandRight]);

                    //draw left leg
                    drawLine(skeleton.Joints[JointType.HipCenter], skeleton.Joints[JointType.HipLeft]);
                    drawLine(skeleton.Joints[JointType.HipLeft], skeleton.Joints[JointType.KneeLeft]);
                    drawLine(skeleton.Joints[JointType.KneeLeft], skeleton.Joints[JointType.AnkleLeft]);
                    drawLine(skeleton.Joints[JointType.AnkleLeft], skeleton.Joints[JointType.FootLeft]);

                    //draw right leg
                    drawLine(skeleton.Joints[JointType.HipCenter], skeleton.Joints[JointType.HipRight]);
                    drawLine(skeleton.Joints[JointType.HipRight], skeleton.Joints[JointType.KneeRight]);
                    drawLine(skeleton.Joints[JointType.KneeRight], skeleton.Joints[JointType.AnkleRight]);
                    drawLine(skeleton.Joints[JointType.AnkleRight], skeleton.Joints[JointType.FootRight]);
                }
            }//end foreach
        }//end method
    }//end class
}

No comments:

Post a Comment