Facebook RSS Feed
 
Kinect & Leap Motion: Kinect ile İmleç Kontrolü
Tarih: 06.09.2012, Platform: .NET 4.5, IDE: Visual Studio 2012, Level: 200

Kinect ile varolan uygulamalarımızı kontrol etmenin en kolay yolu, el hareketlerimize göre imleci yönetmek olacaktır. Bu yöntemle, özellikle kontrolleri geniş uygulamalar Kinect ile kullanılabilir. Birkaç gesture desteği ile Windows 8 uygulamalarında başarılı sonuçlar elde edilecektir...

Ön Bilgiler

Geliştireceğimiz uygulamada, seated mode ve near mode özelliklerini kullanacağız. Bu fonksiyonlar yalnızca Kinect for Windows sensöründe bulunuyor. Xbox sensörü ile geliştirme yapacaksanız ilgili fonksiyonları devre dışı bırakabilirsiniz.

Çalışma Mantığı

Uygulamamızda, sağ elimizin X ve Y pozisyonuna göre imleç kontrolü yapacağız. Referans noktası olarak boynumuzu alacağız. Elimizi boynumuzdan sağa doğru ne kadar uzaklaştırırsak, ekran çözünürlüğüne orantılı olarak imleç de o kadar sağ tarafa gidecek. Benzer şekilde, yükseklik için de aynı mantık işleyecek. İmlecin yalnızca elimiz ilerideyken hareket etmesi için boynumuz ile sağ elimizin Z değerlerinin farkını alacağız. Bu değer -örneğin- 40cm'den fazlaysa, imleç hareket edecek. 40cm'den düşükse imleç serbest kalacak.

İmleci kontrol etmek için, İmleç Kontrol sınıfı oluşturacağız. Bu sınıfta tanımlayacağımız metodlar ile imleci X ve Y koordinatlarında hareket ettirebilecek, sağ ve sol tıklayabilecek ve fare tekerleği simulasyonu yapabileceğiz.

Uygulama Kodları

Visual Studio ile bir WPF uygulaması oluşturup, referanslarına "Microsoft.Kinect.dll", "System.Drawing.dll" ve "System.Windows.Forms.dll" dosyasını ekleyelim. ("System.Drawing.dll" ve "System.Windows.Forms.dll" referanslarına imleci kontrol edebilmek için ihtiyaç duyuyoruz.)

Öncelikle, imleç kontrolünü sağlayacağımız ImlecKontrol sınıfını oluşturacağız.

[C#] ImlecKontrol.cs

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;
 
namespace KinectImlec
{
    class MouseControl
    {
        private bool solButonDurumu = false;
 
        [DllImport("user32.dll")]
        private static extern void mouse_event(
            UInt32 dwFlags, UInt32 dx, UInt32 dy, UInt32 dwData, IntPtr dwExtraInfo);
        private const UInt32 MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const UInt32 MOUSEEVENTF_LEFTUP = 0x0004;
        private const UInt32 MOUSEEVENTF_WHEEL = 0x0800;
 
        private void LeftButtonUp()
        {
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, new System.IntPtr());
        }
 
        private void LeftButtonDown()
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, new System.IntPtr());
        }
 
        private void TurnMouseWheel(UInt32 amount)
        {
            mouse_event(MOUSEEVENTF_WHEEL, 0, 0, amount, new System.IntPtr());
        }
 
        /// <summary>
        /// İmleci belirtilen pozisyona götürür.
        /// </summary>
        /// <param name="x">X Pozisyonu</param>
        /// <param name="y">Y Pozisyonu</param>
        public void Git(int x, int y)
        {
            Cursor.Position = new Point(x, y);
        }
 
        /// <summary>
        /// İmleci belirtilen pozisyona götürür.
        /// </summary>
        /// <param name="p">Pozisyon</param>
        public void Git(Point p)
        {
            Cursor.Position = p;
        }
 
        /// <summary>
        /// İmlecin bulunduğu noktaya sol tıklar ve bırakır.
        /// </summary>
        public void SolTikla()
        {
            LeftButtonDown();
            LeftButtonUp();
        }
 
        /// <summary>
        /// İmlecin bulunduğu noktaya çift tıklar.
        /// </summary>
        public void CiftTikla()
        {
            SolTikla();
            SolTikla();
        }
 
        /// <summary>
        /// İmlecin bulunduğu noktaya sol tıklar ve basılı bırakır.
        /// </summary>
        public void SolBas()
        {
            if (!solButonDurumu)
            {
                solButonDurumu = true;
                LeftButtonDown();
            }
        }
 
        /// <summary>
        /// Sol butonu serbest bırakır.
        /// </summary>
        public void SolBirak()
        {
            if (solButonDurumu)
            {
                solButonDurumu = false;
                LeftButtonUp();
            }
        }
 
        /// <summary>
        /// Fare tekerleğinin kaydırma işlemini gerçekleştirir.
        /// </summary>
        /// <param name="miktar">Dönüş miktarı</param>
        public void Kaydir(UInt32 miktar)
        {
            TurnMouseWheel(miktar);
        }
    }
}

- ImlecKontrol sınıfındaki Git metoduna vereceğimiz point parametresi ile imlecin istediğimiz pozisyona gitmesini sağlanır.
- SolTikla metodu, sol tık yapar ve tıklamayı serbest bırakır.
- CiftTikla metodu, Tikla metodunu 2 kez çalıştırır.
- SolBas metodu, sol tık yapar ve fare butonunu basılı bırakır. Bu metodu gelecek projelerde, taşıma ve harita kaydırma gibi işlemlerde kullanacağız.
- SolBirak metodu, sol tık yapılmışsa bunu serbest bırakır.
- Kaydir metodu ise, vereceğimiz + / - değere göre fare tekerleğini çevirme simulasyonu yapar. Harita uygulamaları gibi tekerlekle zoom yapılan uygulamaları kontrol edebilmemizi sağlar.

[XAML] MainWindow.xaml

<Window x:Class="KinectImlec.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Kinect İmleç" Height="200" Width="300"
        Loaded="Window_Loaded" Closing="Window_Closing"
        WindowState="Minimized" WindowStartupLocation="CenterScreen">
    <Grid>
 
    </Grid>
</Window>

Uygulamamızı simge durumuna küçültülmüş olarak başlatacağız. Loaded ve Closing eventlerinde Kinect başlatılacak ve durdurulacak. Kinect'den gelecek pozisyon bilgisine göre imleç kontrolü sağlanacak...

[C#] MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Kinect;
 
namespace KinectImlec
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
 
        KinectSensor kinect;
        Skeleton[] skeletons = new Skeleton[6];
 
        ImlecKontrol imlec = new ImlecKontrol();
 
        int ekranGenisligi = (int)System.Windows.SystemParameters.PrimaryScreenWidth;
        int ekranYuksekligi = (int)System.Windows.SystemParameters.PrimaryScreenHeight;
        bool solTiklandi = false;
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Kinect bağlıysa, belirtilen parametrelere göre başlat
            if (KinectSensor.KinectSensors.Count > 0)
            {
                kinect = KinectSensor.KinectSensors[0];
 
                // Hareket yumuşatma parametreleri
                TransformSmoothParameters tsp = new TransformSmoothParameters();
                tsp.Smoothing = 0.55f;
                tsp.Correction = 0.1f;
                tsp.Prediction = 0.1f;
                tsp.JitterRadius = 0.4f;
                tsp.MaxDeviationRadius = 0.4f;
 
                // Sisteme bağlı ilk Kinect'i başlat
                kinect.Start();
 
                // Derinlik algılamasında yakın modu etkinleştir
                kinect.DepthStream.Range = DepthRange.Near;
 
                // Derinlik algılaması yakın moddayken iskelet algılamasını etkinleştir
                kinect.SkeletonStream.EnableTrackingInNearRange = true;
 
                // İskelet algılamasında oturma modunu kullan
                kinect.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
 
                // Derinlik akışını başlat (Yakın modun aktif olabilmesi için gerekli)
                kinect.DepthStream.Enable();
 
                // İskelet verisi akışını belirtilen hareket yumuşatma parametrelerine göre başlat
                kinect.SkeletonStream.Enable(tsp);
 
                // İskelet verisi güncellendiğinde tetiklenecek event handler'ı oluştur
                kinect.SkeletonFrameReady +=
                    new EventHandler<SkeletonFrameReadyEventArgs>(Kinect_SkeletonFrameReady);
            }
        }
 
        private void Kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            Skeleton iskelet;
 
            try
            {
                // İskelet verisini al
                if (e.OpenSkeletonFrame() != null)
e.OpenSkeletonFrame().CopySkeletonDataTo(skeletons);                 // İlk algılanan iskeleti seç                 iskelet = (from s in skeletons                            where s.TrackingState == SkeletonTrackingState.Tracked                            select s).FirstOrDefault();             }             catch (Exception)             {                 iskelet = null;             }             // İskelet algılanmışsa veriyi işle             if (iskelet != null)             {                 // Kullanılacak eklem bilgilerini, ImlecHareket metoduna aktar                 ImlecHareket(iskelet.Joints[JointType.HandRight],
  iskelet.Joints[JointType.ShoulderCenter]);             }         }         private void ImlecHareket(Joint sagEl, Joint boyun)         {             // Boyun ile eller arasındaki mesafeye göre imleç pozisyonunu belirle             // (Hassasiyeti ayarlamak için 3000 değerini değiştirin.)             int imlecX = (int)((sagEl.Position.X - boyun.Position.X) * 3000);             int imlecY = (int)((boyun.Position.Y - sagEl.Position.Y) * 3000);             // İmlecin ekran sınırları dışına çıkmaması için sınırlama             if (imlecX < 0) imlecX = 0;             else if (imlecX > ekranGenisligi) imlecX = ekranGenisligi;             if (imlecY < 0) imlecY = 0;             else if (imlecY > ekranYuksekligi) imlecY = ekranYuksekligi;             // İmleci oynat             imlec.Git(imlecX, imlecY);             // Sağ el ileriye uzatıldığında sol tıkla             // (Tıklama mesafesini ayarlamak için 0.45 değerini değiştirin.)             if (boyun.Position.Z - sagEl.Position.Z > 0.45)             {                 // El ilerideyken, birden fazla tıklamanın yapılmaması için                 // "solTiklandi" değişkenini ile kontrol sağlıyoruz                 if (!solTiklandi)                 {                     solTiklandi = true;                     // Sol tıklama komutu gönder                     // (Çift tıklama için, "imlec.CiftTikla()" metodunu kullanın.)                     imlec.SolTikla();                 }             }             else             {                 if (solTiklandi)                     solTiklandi = false;             }         }         private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)         {             // Uygulama kapanırken, Kinect çalışıyorsa Kinect'i durdur             if (kinect.IsRunning)                 kinect.Stop();         }     } }

Uygulama çalıştığında, elimizin boynumuza olan pozisyonuna göre imleç hareket edecek. Elimizi ileriye uzattığımızda, o an imlecin bulunduğu pozisyona tıklanacak. İmleç hassasiyetini ve tıklama mesafesini kod içerisinde belirtilen parametreler ile değiştirebilirsiniz.

Geliştirdiğimiz bu uygulama, imleç kontrolünün en temelde nasıl gerçekleştiğini gösteriyor. Farklı yöntemler ile birleştirilerek farklı amaçlara uygun uygulamalar elde edilebilir...


Ek Dosya: Uygulama Kodları
Okunma Sayısı: 2619

comments powered by Disqus
 
Hoşgeldiniz!
Son güncelleme: 25.12.2016
-
Yeni Teknik Yazılar
Latte Panda İncelemesi
Turta IoT HAT İncelemesi
USB Gamepad Kullanımı
GPIO Kullanımı
VEML6075 UV Sensör Kullan...
-
İlgili Gruplar
.NET MF ve Gadgeteer FB Grubu
İst. IoT & Wearables Meet-up
-
 

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.Copyright © 1999 - 2017, Umut Erkal. Bu materyal, "Creative Commons Public Licence" ile sunulmuştur.
Kaynak göstererek ve ücretsiz olarak, aynı şartlar altında paylaşabilir ve kullanabilirsiniz. | Kullanım Sözleşmesi