Facebook RSS Feed
 
Kinect & Leap Motion: Kinect ile Bing Maps Kontrolü
Tarih: 11.09.2012, Platform: .NET 4.5, IDE: Visual Studio 2012, Level: 200

El haraketleriyle harita kontrolü, Kinect ile gerçekleştireceğimiz ilgi çekici uygulamalardan yalnızca birisi. Bing Maps yada Google Maps uygulamalarının kontrollerine baktığımızda; imleç kontrolü, sürükleme ve fare tekerleği çevirerek yakınlaştırma / uzaklaştırma yaptığımızı görüyoruz. Bu yöntemler, Kinect ile kolaylıkla taklit edebileceğimiz kontroller arasında yer alıyor...

Öngereksinimler

Geliştireceğimiz uygulamada, Kinect ile İmleç Kontrolü başlıklı yazıda üzerinde durduğumuz imleç kontrol yöntemlerini kullanacağız.

Bilgisayarınıza Bing Maps WPF kontrolünü kurmanız gerekiyor. Kurulum dosyalarını buradan indirebilirsiniz. Bing Maps WPF kontrolü hakkında detaylı bilgi almak için buradan faydalanabilirsiniz.

Kinect for Windows SDK'sına www.kinectforwindows.com adresinden ulaşabilirsiniz.

Çalışma Mantığı

Uygulamamızı 3 parçaya ayıralım. İlk parçamız Bing Maps kontrolü. Tam ekran çalışacak bir WPF penceresi içerisine Bing Maps kontrolünü yerleştireceğiz. Bu kontrol ile online harita görüntülerini webde olduğu gibi uygulamamızda da kullanabileceğiz.

İkinci parçamız, ImlecKontrol sınıfı. Bu sınıftaki metodlar aracılığıyla imleci istenilen noktaya götürebileceğiz ve harita kaydırma işlemi yapabileceğiz.

Son parçamız ise Kinect kodları. Kinect'in raporlayacağı iskelet pozisyonuna göre ImlecKontrol sınıfına pozisyon bilgisi aktaracağız ve Bing Maps kontrolüne zoom komutu vereceğiz.

Uygulama Kodları

Visual Studio ile bir WPF uygulaması oluşturalım ve proje referanslarına "Microsoft.Kinect.dll", "Microsoft.Maps.MapControl.WPF", "System.Drawing.dll", "System.Windows.Forms.dll" dosyalarını ekleyelim.

Öncelikle, imleç kontrolünü sağlamak için 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 KinectBingMaps
{
    class ImlecKontrol
    {
        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.

Uygulamamızın tasarımında yalnızca Grid'e Bing Maps kontrolünü ekliyoruz.

[XAML] MainWindow.xaml

<Window x:Class="KinectBingMaps.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"
        Title="Kinect" Height="600" Width="800" WindowStartupLocation="CenterScreen"
        Loaded="Window_Loaded" Closing="Window_Closing"
        KeyDown="Window_KeyDown" WindowState="Maximized">
    <Grid>
        <m:Map Name="harita" CredentialsProvider="Your Key is here"
               Center="41.0128, 28.9744" ZoomLevel="16"/>
    </Grid>
</Window>

Bing Maps eklendikten sonra aşağıdaki görüntüyü alacağız:

-

Haritanın ortasında görünen lisans uyarısını kaldırmak için, www.microsoft.com/maps/developers adresinden bir anahtar oluşturup XAML üzerindeki "Your Key is here" yazan bölüme eklemeniz gerekiyor.

Uygulamamızda her iki elimizi 45 cm kadar ileriye uzatarak birbirine yaklaştırıp uzaklaştırdıkça, haritanın zoom seviyesi değişecek. Sağ elimizi 45 cm uzattığımızda haritayı kaydırabileceğiz. Bunun dışındaki durumlarda ise imleç serbest hareket edecek, tıklama yada kaydırma işlemi gerçekleştirmeyecek. Bu kombinasyonları birleştirdiğimizde, havada sanki bir yüzeyi dikey yada yatay kaydırıyormuşuz gibi haritayı kaydırabileceğiz...

Bu işlemleri gerçekleştirecek kod kısmı şöyle olacak:

[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;
using Microsoft.Maps.MapControl.WPF;
 
namespace KinectBingMaps
{
    /// <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;
 
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            harita.Mode = new AerialMode();
 
            // 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, HaritaKontrol metoduna aktar                 HaritaKontrol(iskelet.Joints[JointType.HandRight],                     iskelet.Joints[JointType.HandLeft],                     iskelet.Joints[JointType.ShoulderCenter]);             }         }         private void HaritaKontrol(Joint sagEl, Joint solEl, Joint boyun)         {             // Mod seçimi:             // Her iki el de ilerideyse, zoom moduna gir             // Boyun ile elin Z pozisyonu farkı, o elin kaç cm uzatıldığını verir.             // 0.45 = 45cm değerini değiştirerek zoom modu uzaklığını ayarlayabilirsiniz.             if (boyun.Position.Z - sagEl.Position.Z > 0.45 &&                 boyun.Position.Z - solEl.Position.Z > 0.45)             {                 // Eller arası yatay farka göre zoom oranını belirle                 double zoom = (sagEl.Position.X - solEl.Position.X) * 15;                 // En yüksek ve düşük zoom sınırlaması                 if (zoom > 15) zoom = 15;                 else if (zoom < 5) zoom = 5;                 // Zoom seviyesini haritaya gönder                 harita.ZoomLevel = zoom;             }             // Her iki el ileride değilse, imleç kontrol moduna gir             else             {                 // İmleç pozisyonunu boyun ile eller arasındaki mesafeye göre belirle                 int imlecX = (int)((sagEl.Position.X - boyun.Position.X) * 3000);                 int imlecY = (int)((boyun.Position.Y - sagEl.Position.Y) * 3000);                 // İmlecin ekran çözünürlüğü 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 pozisyonlandır                 imlec.Git(imlecX, imlecY);                 // İmleç tıklama ve bırakma seçimi:                 // Sağ el ilerideyse, haritayı oynatmak için tıkla ve imleci basılı tut.                 // Kaydırma için el uzaklığı mesafesini 0.45'i değiştirerek ayarlayabilirsiniz.                 if (boyun.Position.Z - sagEl.Position.Z > 0.45)                 {                     imlec.SolBas();                 }                 // Sağ el normal uzaklıktaysa tıklamayı serbest bırak.                 // Bu durumda, imleç serbest hareket eder.                 else                 {                     imlec.SolBirak();                 }             }         }         private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)         {             // Uygulama kapanırken, Kinect çalışıyorsa Kinect'i durdur             if (kinect.IsRunning)                 kinect.Stop();         }         private void Window_KeyDown(object sender, KeyEventArgs e)         {             // Escape tuşuna basıldığında uygulamayı sonlandır             if (e.Key == Key.Escape) this.Close();         }     } }

Uygulama çalışırken bilgisayarınızın imleci Kinect tarafından kontrol edilecek ve fareniz işlemeyecek. Uygulamayı sonlandırmak için Esc tuşunu kullanabilirsiniz.

Kinect ile harita kontrol uygulaması, imleç kontrolünü kullanarak geliştireceğimiz ilgi çekici uygulamalardan yalnızca birisi. Benzer yöntemlerle bir çok proje hayata geçirilebilir...


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

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