Leap Motion'a ilk bakış, ilk dokunuş

0 dakikada yazıldı

26832 defa okundu

Düzenle

Kaç ay oldu hatırlamıyorum ama epey zaman oldu Leap Motion'ın Leap cihazı ile ilgili ilk videoyu internette izlediğimde "İşte bu!" demiştim. Kinect'in el hareketleri için daha hassas ve bir o kadar da ufaltılmış hali gibi gözüküyordu. Her yere gömülebilir minik bir cihaz olarak Leap ile yapılabilecek şeyler beni ciddi heyecanlandırmıştı ki hızlıca "Early Adoption" programına başvurdum hatta bir de cihaz ön sipariş ettim. Tüm bu hikayenin sonunda geçen hafta cihaz elime ulaştı ve tabi ki deneyimlerimi paylaşma zamanı geldi :)

Küçük, minik bir şey

Gerçekten de cihaz süper ufak birşey. Çakmak büyüklüğünde desem hiç de yalan olmaz. Bu boyutu ile her yere konulabilir ve entegre edilebilir. Üreticilerin cihazın kullanılacağını varsaydıkları konum monitörünüz ile klavyenizin arasında boşluk. Kaba olarak cihazın üzerinden yukarıya doğru ters bir piramit hayal edin, işte tam o alanı tarıyor cihaz. 20cm'den başlıyor tarama mesafesi ve 65cm'ye kadar hareketleri yakalayabiliyor. Bu özelliği ise zaten Kinect'ten epey bir ayrılıyor diyebiliriz.

Ufacık cihazla 10 parmak yakalamak
mümkün.Ufacık cihazla 10 parmak yakalamak mümkün.

Cihazı ilk kurduğunuzda sitesinden de yazılımını indirerek kurmanız gerekiyor. Yazılımı ile beraber kendi marketplace'i de geliyor. AirSpace adındaki yazılımı kurup ister ücretsiz ister ücretli bir çok Leap uyumlu uygulamayı indirebiliyorsunuz. Uygulamalar içerisinde her tür içerik var, oyunlardan tutun Windows 8'in başlat menüsünü Leap ile kullanılabilir hale getiren eklentilere kadar birçok şey mevcut.

SDK var mı? SDK?

Olmaz mı? Tabi ki Leap'in kendi developer programı ve SDK'i de var. C# için süper dost canlısı olduklarını söylemem ama haksızlık de etmiyim. Cihazın her özelliğini rahatlıkla kullanabiliyorsunuz. Bir tane minik sample bile geliyor SDK ile beraber. Ama özellikle Microsoft tarafındaki developerların MS'ten alışkın oldukları SDK kalitesini beklememeleri gerekecek. Hem dokümantasyon, hem de örnekler anlamında SDK epey kısıtlı bir içeriğe sahip. Diğer yandan SDK ile beraber gelen kütüphaneler de cihazın Firmware'i de daha RTM olmuş değil yani hala geliştiriliyorlar ve zaten geliştirilmeleri de gerekiyor. Bu konuya sonra tekrar göz atacağız :)

Leap SDK ile beraber .NET 3.5 ve 4.0 SDK'leri geliyor. Bunlardan uygun DLL'i SDK'den alıp referans olarak örnek bir WPF projesine ekledim ve neler yapabilirim diye hızlıca bir baktım. Unutmadan, referans alamayacağınız Native 2 kütüphaneyi de 32-bit veya 64-bit seçeneklerine göre uygulamanızın klasöründe bulundurmanız şart. Ben "LeapCSharp.NET4.0.dll"'i referans alıp "Leap.dll" ve "LeapCSharp.dll" dosyalarını da projeye ekleyip "Copy Always" olarak ayarladım.

Leap ile çalışırken birkaç konsept var. Bunlardan ilk Controller nesnesi. Bu nesne alıcı cihazı temsil ediyor diyebiliriz. Listener adındaki nesneler de bu cihazlardan veri almamızı sağlıyorlar. Sensörden aldığımız her veri paketi bir Frame olarak kabul ediliyor. Bu noktada Kinect ile uğraşanlara bu senaryoların çoğu zaten tanıdık gelecektir. Gelen veride RAW input pointlerin yanı sıra farklı Gesture'lar da gelebiliyor. Bunlar SDK içerisinde tanımlı ve tek tek enable edilmesi gerekiyor ki yardımcı kütüphaneler gerekli işleme süreçlerini arka planda başlatsın. Aslında bir anlamda bizim adımıza bazı sayılı Gesture'lar için RAW data SDK tarafından bizim adımızda yazılımsal olarak işlenebiliyor.

[C#]

        Leap.Controller controller;\         SampleListener listener;\ \         void MainWindow_Loaded(object senderRoutedEventArgs e)\         {\             Leap.Controller controller = new Leap.Controller();\             SampleListener listener = new SampleListener();\             listener.ParmakVar += listener_ParmakVar;\             controller.AddListener(listener);\         }

Yukarıdaki kodda hızlı bir şekilde Controller ve Listener yaratıyorum. Listener'ın kendi iç yapısına birazdan geleceğiz. Ama öncesinde buraya bir göz atalım. Controller'a listener vermek dışında pek de birşey yok aslında elimizde :) Sonrasında Listener'ın bize veri göndermesini bekliyoruz.

[C#]

        void MainWindow_Unloaded(object senderRoutedEventArgs e)\         {\             controller.RemoveListener(listener);\             controller.Dispose();\         }

Önemli noktalardan biri Controller ile işiniz bittiğinde Listener'ı detach'layıp doğal olarak Controller'ı da serbest bırakmak.

[C#]

    class SampleListener : Listener\     {\         public override void OnFrame(Controller controller)\         {\             Frame frame = controller.Frame();\             \             if (!frame.Hands.Empty)\             {\                 Hand hand = frame.Hands[0];\ \                 FingerList fingers = hand.Fingers;\                 if (!fingers.Empty)\                 {\                     if (ParmakVar != null)\                     {\                         ParmakVar(fingers);  \                     }\                 }\             }\         }\ \         public delegate void ParmaklarGelir(FingerList parmaklar);\         public event ParmaklarGelir ParmakVar;\     }

Gelelim bizim basit Listener'a... Aslında SDK içerisinde çok daha karmaşık ve neredeyse SDK'in tüm özelliklerini kullanan bir Listener mevcut ama üzerinden birkaç takla atmak gerekiyor kullanılabilir hale getirmek için. Ben hazır o taklaları atarken biraz da örneği basitleştirmek adına ortalığı temizledim. Bizim örneğimizde sadece elin parmaklarına ihtiyacımız olduğu için eğer bir el varsa ilkini alıp onun da parmakları yakalanmış ise parmakları alıp bir event ile parmak listesini dışarı atıyorum. Böylece biraz önce kodumuz bu event'i dinleyerek Listener'dan istediği temiz veriyi alabilecek.

Ben örnek uygulamamda beş parmağı temsil edecek beş Ellipse kullandım. Bunlar XAML tarafında tanımlı ve P1, P2 gibi isimlere sahip.

[C#]

        void listener_ParmakVar(Leap.FingerList parmaklar)\         {\             this.Dispatcher.Invoke((Action)(() =>\             {\                 ParmakPozisyonla(P1parmaklar[0].TipPosition);\                 ParmakPozisyonla(P2parmaklar[1].TipPosition);\                 ParmakPozisyonla(P3parmaklar[2].TipPosition);\                 ParmakPozisyonla(P4parmaklar[3].TipPosition);\                 ParmakPozisyonla(P5parmaklar[4].TipPosition);\             })); \             \         }\ \         void ParmakPozisyonla(Ellipse PLeap.Vector Pozisyon)\         {\             P.RenderTransformOrigin = new Point(0.50.5);\             Canvas.SetLeft(PPozisyon.x);\             Canvas.SetTop(PPozisyon.y);\             P.Height = Math.Abs(Pozisyon.z);\             P.Width = P.Height;\         }

Listener'ın eventinden gelen veriyi kullanabilmek için Dispatcher ile UIThread'e çıkmam gerekiyor. Malumunuz UIThread'in sahip olduğu Ellipse'lerin konumunu vs değiştirmemiz gerekecek gelen veriye göre. Aslında kodun geri kalanı artık WPF ile alakalı. Nesnelerin merkez noktasını belirt ve sonra da elindeki Vektör'lerden pozisyonu alıp nesnelerin yukarıdan ve aşağıdan mesafelerine aktar. Tüm yaptığım bu. Tabi biraz daha atraksyon olsun diye parmakların Z koordinatını da Ellipse'lerin büyüklüğüne bağladım. Yani böytece eğer sensör monitörünüzün önündeyse parmaklar sağa gidince Ellipse'ler sağa, sola gidince sola giderken parmaklarınız monitöre yaklaşırken Ellipse'ler büyüyecek, uzaklaşınca da küçülecek.  İşte bu kadar :) Yaptığın bu mini örneğin kaynak kodlarını indirmek isterseniz GitHub'a koydum.

Vaatler güzel de sonuç?

İtiraf etmem lazım ki ne cihaz ne de SDK bende "Production Quality" hissiyatı yaratmadı. Cihaz dışarıdan epey güzel gözüküyor ama verdiği datanın kullanılabilir olması için parazitlerin epey bir temizlenmesi şart. Bunu tabi ki siz de kendiniz kod yazarak yapabilirsiniz ama ben bu tür cihazların RAW data verirken basit bir Karaköy sensörü olmaktan öteye geçip biraz daha developer dostu veri sağlaması gerektiğini düşünüyorum. Bu noktada Leap Motion'ın daha yapması gereken çok şey var. Şu anda çat diye alıp SDK ile birşeyler çıkartmak pek mümkün değil. Üzerine uğraşılırsa tabi ki süper şeyler çıkartılabilir. Şu an için kendi AppStore'larına baktığımda da uygulamalarda aslında bu eksikliği hissedebiliyorsunuz. Detection Precision'ı epey kötü durumda ama bunun nedeni sensörden öte yazılım kaynaklı.

Sonuç olarak :) ben Leap Motion özellikle ufaklığı ile çok değerli bir cihaz çünkü Kinect'in giremediği bir sürü yere girebilir gibi duruyor. Detaylı detection sistemi de doğal olarak tarama alanının farklılığı nedeni ile Kinect'ten iyi. Kinect vücut iskeletine odaklanırken Leap Motion insan eline ve eldeki cihazlara odaklanıyor. Örneğin elinizde tuttuğunuz bir kalemi de pointer olarak algılabiliyor. Umuyorum ki zamanla, gerekli yazılım desteğinin de gelişmesi ile süper bir noktaya gelecektir.

Görüşmek üzere!