Makale Özeti

Bu makalemde sizlere Kinect’ten aldığımız iskelet verilerini kullanarak iskeletimizi çizgilerle nasıl çizebileceğimizi anlatacağım.

Makale

Herkese merhaba,

Bu makalemde sizlere Kinect’ten aldığımız iskelet verilerini kullanarak iskeletimizi çizgilerle nasıl çizebileceğimizi anlatacağım. Zaman kaybetmeden işe başlayalım.

Öncelikle Visual Studio’dan bir WPF projesi oluşturuyoruz. Ardından projemize “Microsoft.Kinect.dll”  dosyasını referanslarımıza ekliyoruz. Ardından projemizin .xaml kodunu aşağıdaki gibi hazırlıyoruz.

<Window x:Class="Iskelet.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="480" Width="640" Closing="Window_Closing">
    <Grid Name="a">
        
    </Grid>
</Window> 

MainPage.xaml.cs dosyamızın içeriğine geçmeden iskelet bilgisine dair bazı bilgileri vermek istiyorum.


- Shoulder Center: Boyun

- Shoulder Left: Sol Omuz

- Shoulder Right: Sağ Omuz

- Elbow Left: Sol Dirsek

- Elbow Right: Sağ Dirsek

- Wrist Left: Sol El Bileği

- Wrist Right: Sağ El Bileği

- Hand Left: Sol El

- Hand Right: Sağ El

- Spine: Karın

- Hip Center: Kuyruk Sokumu

- Hip Left: Sol Kalça

- Hip Right: Sağ Kalça

- Knee Left: Sol Diz

- Knee Right: Sağ Diz

- Ankle Left: Sol Ayak Bileği

- Ankle Right: Sağ Ayak Bileği

- Foot Left: Sol Ayak

- Foot Right: Sağ Ayak


  

Bu bilgilerden sonra MainPage.xaml.cs dosyamızı  aşağıdaki şekilde hazırlıyoruz.

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.Shapes;
using Microsoft.Kinect;
using System.Collections;

namespace Iskelet
{    
    public partial class MainWindow : Window
    {
        private Skeleton[] skeletons = new Skeleton[0];//iskelet verilerini tutacağımız iskelet dizimiz
        private Skeleton skeleton; //işlem yapacağımız iskelet  
        private int sayac = 0; 
        private Joint[,] dizi = new Joint[19, 2]; // eklem bilgilerini tutacağımız eklem dizisi
        private List<Line> list = new List<Line>(); //eklemler arasında çizilecek olan çizgiler

        public MainWindow()
        {
            InitializeComponent();           
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            if (KinectSensor.KinectSensors.Count > 0)
            {
                KinectSensor.KinectSensors[0].Start(); //Kinect'i başlatıyoruz
                KinectSensor.KinectSensors[0].SkeletonStream.Enable(); //iskelet bilgilerini almasını etkinleştiriyoruz
                KinectSensor.KinectSensors[0].SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(MainWindow_SkeletonFrameReady);
            }

            for (int i = 0; i < 19; i++) //18 adet çizgi çizeceğiz
            {
                Line line = new Line();
                list.Add(line);
            }
        }
        void MainWindow_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {           
            using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame != null)
                {
                    skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
                    skeletonFrame.CopySkeletonDataTo(skeletons);  //Gelen iskelet bilgisini skeletons dizisine kopyala
                }

                foreach (Skeleton skel in skeletons)
                {
                    if (skel.TrackingState == SkeletonTrackingState.Tracked)  
                    {
                        skeleton = skel;
                        this.DiziyeEklemEkle(skeleton); 
                    }
                }
            }
        }

        private void DiziyeEklemEkle(Skeleton skeleton)
        {   
            //Gövdemizi çizdirmek için kullanılan eklem bilgileri
            dizi[0, 0] = skeleton.Joints[JointType.Head];
            dizi[0, 1] = skeleton.Joints[JointType.ShoulderCenter];
            dizi[1, 0] = skeleton.Joints[JointType.ShoulderCenter];
            dizi[1, 1] = skeleton.Joints[JointType.ShoulderLeft];
            dizi[2, 0] = skeleton.Joints[JointType.ShoulderCenter];
            dizi[2, 1] = skeleton.Joints[JointType.ShoulderRight];
            dizi[3, 0] = skeleton.Joints[JointType.ShoulderCenter];
            dizi[3, 1] = skeleton.Joints[JointType.Spine];
            dizi[4, 0] = skeleton.Joints[JointType.Spine];
            dizi[4, 1] = skeleton.Joints[JointType.HipCenter];
            dizi[5, 0] = skeleton.Joints[JointType.HipCenter];
            dizi[5, 1] = skeleton.Joints[JointType.HipLeft];
            dizi[6, 0] = skeleton.Joints[JointType.HipCenter];
            dizi[6, 1] = skeleton.Joints[JointType.HipRight];           

            // Sol kolu çizdirmek için kullanılan eklem bilgileri
            dizi[7, 0] = skeleton.Joints[JointType.ShoulderLeft];
            dizi[7, 1] = skeleton.Joints[JointType.ElbowLeft];
            dizi[8, 0] = skeleton.Joints[JointType.ElbowLeft];
            dizi[8, 1] = skeleton.Joints[JointType.WristLeft];
            dizi[9, 0] = skeleton.Joints[JointType.WristLeft];
            dizi[9, 1] = skeleton.Joints[JointType.HandLeft];

            //Sağ kolu çizdirmek için kullanılan eklem bilgileri
            dizi[10, 0] = skeleton.Joints[JointType.ShoulderRight];
            dizi[10, 1] = skeleton.Joints[JointType.ElbowRight];
            dizi[11, 0] = skeleton.Joints[JointType.ElbowRight];
            dizi[11, 1] = skeleton.Joints[JointType.WristRight];
            dizi[12, 0] = skeleton.Joints[JointType.WristRight];
            dizi[12, 1] = skeleton.Joints[JointType.HandRight];

            // Sol bacağı çizdirmek için kullanılan eklem bilgleri
            dizi[13, 0] = skeleton.Joints[JointType.HipLeft];
            dizi[13, 1] = skeleton.Joints[JointType.KneeLeft];
            dizi[14, 0] = skeleton.Joints[JointType.KneeLeft];
            dizi[14, 1] = skeleton.Joints[JointType.AnkleLeft];
            dizi[15, 0] = skeleton.Joints[JointType.AnkleLeft];
            dizi[15, 1] = skeleton.Joints[JointType.FootLeft];

            // Sağ bacağı çizdirmek için kullanılan eklem bilgileri
            dizi[16, 0] = skeleton.Joints[JointType.HipRight];
            dizi[16, 1] = skeleton.Joints[JointType.KneeRight];
            dizi[17, 0] = skeleton.Joints[JointType.KneeRight];
            dizi[17, 1] = skeleton.Joints[JointType.AnkleRight];
            dizi[18, 0] = skeleton.Joints[JointType.AnkleRight];
            dizi[18, 1] = skeleton.Joints[JointType.FootRight];
            
            Ciz();            
        }

        private void Ciz()
        {
            for (int i = 0; i < 19; i++)
            {
                list[i].StrokeThickness = 4;
                list[i].Stroke = System.Windows.Media.Brushes.Black;
                list[i].X1 = (dizi[i, 0].Position.X + 1) * 320; 
                list[i].X2 = (dizi[i, 1].Position.X + 1) * 320;
                list[i].Y1 = 480 - (dizi[i, 0].Position.Y + 1) * 220;
                list[i].Y2 = 480 - (dizi[i, 1].Position.Y + 1) * 220;

                //Yukarıdaki işlemlerde +1, 220 ve 320'yi işleme dahil etmemizin sebebi alınan iskelet bilgilerini çizgilerle ifade ederken
                //x ve y değerlerini öteleme ve ölçekleme yapmaktır. Çünkü gelen bilgilerin değişim aralığı 0,000 gibi çok küçük.Biz bu değişimleri 
                //görmek için ölçekleme yapmamız lazım. Buradaki rakamlar değişebilir. Ben formumu 640x480 kullandığım için bu şekilde kullandım.
               
                if (sayac < 19) 
                {
                    a.Children.Add(list[i]); //ilk 18 çizgimizi görünmesi için gridimize ekliyoruz. Sonrasında gelen x1,x2,y1,y2 bilgilerini güncelliyoruz
                    sayac++;
                }
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (KinectSensor.KinectSensors.Count > 0)
            {
                foreach (KinectSensor sensor in KinectSensor.KinectSensors)
                    sensor.Stop(); //Kinect'i durduruyoruz
            }
        }
    }
}

Projemiz bitmiştir. :) Kodumuzu çalıştırdığımızda aşağıdaki gibi bir görüntü karşımıza çıkıyor.


 

Başka yollarla da bu işlemi yapabilirsiniz. Örneğin; Çizimleri Line yerine DrawingGroup ile de yapabilirsiniz.

Sonuç olarak sizlere Kinect ile iskeletin algılanması ve bunun biz çizim ile temsil edilmesinden bahsettim. Umarım faydalı olmuştur. Bir sonraki makalemde görüşmek dileğiyle...