Otistik Bireylere Kinect İle Davranış Öğretimi

Benzer belgeler
Öğr. Gör. Hakan YÜKSEL SÜLEYMAN DEMİREL ÜNİVERSİTESİ. Akademik Bilişim

Fırat Üniversitesi DENEY NO: 8 KINECT İLE İNSAN HAREKETLERİNİN ALGILANMASI

İnsan Hareketinin Algılanmasından Yeni Bir Teknoloji Platformu: KİNECT

Karabük Üniversitesi, Mühendislik Fakültesi... WEB TEKNOLOJİLERİ

GENETİK ALGORİTMA GEZGİN SATICI ÖDEVİ

2 ALGORİTMA VE AKIŞ DİYAGRAMLARI

4. Bölüm Programlamaya Giriş

C#.Net & Linq (Language Integrated Query)

Windows form uygulamalarından alışık olduğumuz sabit piksel koordinatları, WPF ile son buldu. WPF uygulamaları farklı çözünürlüklerde çalışsalar bile

İNTERNET TABANLI PROGRAMLAMA

KRİPTOANALİZ DERSİ FİNAL ÖDEVİ. PSO ile TRANSPOSITION CIPHER ÇÖZÜMÜ

HSancak Nesne Tabanlı Programlama I Ders Notları

ASP.NET CLASS KULLANARAK VERİTABANI İŞLEMLERİ

MEKANİZMA TEKNİĞİ (7. Hafta)

Yeni bir proje açarken File New - Web Site diyoruz. Gelen ekranda Visual Basic veya C# seçilebilir. Biz ders kapsamında C# programlama dilini seçtik.

1 GİRİŞ 1 C# Hakkında Genel Bilgiler 1.Net Framework 1 CLR 2 CLR Ve CTS 2 Temel Sınıf Kütüphanesi 3 CIL 3 Algoritma Nedir? 4 Sözde Kod (Pseudocode) 5

İNTERNET TABANLI PROGRAMLAMA- 3.ders

Çalışmamız (Ne Yaptık?) Materyal Metot (Nasıl Yaptık?) Uygulama (Demo) Deneysel Sonuçlar Teşekkür ve Sorular

KATEGORİ MİZANI BAŞLARKEN KATEGORİ NEDİR? NEDEN N İHTİYAÇ DUYULUR?

C# ÖRNEKLERİ.

2 VISUAL STUDIO 2012 GELİŞTİRME ORTAMI

Önce Access açıp,masaüstü ne, vt.mdb adlı veri tabanı dosyasını oluşturuyoruz. Kayıt türünü seçiyoruz

C# Console Uygulamaları ifelse Yapıları 2

Çoktan Seçmeli Değerlendirme Soruları Akış Şemaları İle Algoritma Geliştirme Örnekleri Giriş 39 1.Gündelik Hayattan Algoritma Örnekleri 39 2.Say

PDF. C# Console Örnekleri.

ESKİŞEHİR OSMANGAZİ ÜNİVERSİTESİ EĞİTİM FAKÜLTESİ BÖTE PROJE GELİŞTİRME VE YÖNETİMİ II DERSİ PROJE RAPORU

İNÖNÜ ÜNİVERSİTESİ MÜHENDİSLİK FAKÜLTESİ BİLGİSAYAR MÜHENDİSLİĞİ BÖLÜMÜ 2. SINIF 1. DÖNEM VERİ YAPILARI DERSİ LABORATUAR ÖDEVİ

Algoritma Geliştirme ve Veri Yapıları 9 Ağaç Veri Modeli ve Uygulaması. Mustafa Kemal Üniversitesi

Temel Bilgisayar Programlama Final Sınavı Çalışma Notları

Engelliler İçin Akıllı Ev Otomasyon Sistemi

Özyineleme (Recursion)

2003 yılında P.D.C. de WPF in duyurulması ile beraber yazılım alanında farklılaşmanın başladığını gördük. İlk değişim, tasarım kodlama alanının

Android Ders Notları

Görsel Programlama (Visual Programming) 2.Hafta

EĞİTİMDE BİLGİSAYAR PROGRAMLAMA

HSancak Nesne Tabanlı Programlama I Ders Notları

2.Eclipse açıldıktan sonra Workspace alanı seçilmesi gerekir. Workspace alanı projelerinizin fiziksel olarak bulunduğu kısımdır.

Bu gün dersimizde değişik web kontrollerinin kullanımını gösteren birkaç web sitesi hazırlayacağız. Önce Visual Studio 2005 i açalım.

ÜNİT E ÜNİTE GİRİŞ. Algoritma Mantığı. Algoritma Özellikleri PROGRAMLAMA TEMELLERİ ÜNİTE 3 ALGORİTMA

BMÜ-111 Algoritma ve Programlama. Bölüm 5. Tek Boyutlu Diziler

OKUL HABER EKLEME MODÜLÜ TANITIM DOSYASI. Okul haberlerinizi ilçemiz web sitesinde yayınlayabilmek için aşağıdaki adımları uygulamanız gerekmektedir.

BMÜ-101 ALGORİTMA VE PROGRAMLAMAYA GİRİŞ LABORATUARI

Windows Mobile İşletim Sistemleri İçin Veri Giriş Yazılımı

C# Programlama Dili. İlk programımız Tür dönüşümü Yorum ekleme Operatörler

Kayan Yazı LED Tabela Kullanım Klavuzu

YZM 2116 Veri Yapıları

C# Yazım Kuralları ERCİYES. Ü. BİLGİSAYAR M. COMPUTER PROGRAMMING II 1 FEHİM KÖYLÜ

.. ROBOTİK VE KODLAMA EĞİTİMİ ÇERÇEVESİNDE ÖĞRETİM YILI BİLİŞİM TEKNOLOJİLERİ DERSİ ÜNİTELENDİRİLMİŞ YILLIK DERS PLANI

İl İlçe uygulaması. : Seçilen ile ait ilçeleri listeleyen program. //İl değişkeni için kodu aşağıdaki sayfadan kopyalayınız.

Android Telefonlarla Yol Bozukluklarının Takibi: Kitle Kaynaklı Alternatif Çözüm

Bilgisayar Programcılığı. Görsel Programlama-I. Öğr. Gör. Cansu AYVAZ GÜVEN

1. Hafta MS SQL Server 2008 Kurulum ve Tanıtımı BPR255 Veritabanı. Bu Derste Öğrenecekleriniz: Kurulum:

Mühendislik Fakültesi Elektrik-Elektronik Mühendisliği C Programlama 1. Bölüm C# Programlamaya Giriş

NOT: VERİTABANINDAKİ TABLOLARI OLUŞTURMAYI DA UNUTMAYACAĞIZ.

Dijital (Sayısal) Fotogrametri

Görsel Programlama (Visual Programming) 2.Hafta

İnternet Programcılığı Öğr. Gör. Serkan AKSU PHP de Dizi-Değişkenler, Nesneler. Dizi Oluşturma. Tek Boyutlu Diziler

NESNEYE YÖNELİK PROGRAMLAMA

Programlama Dilleri 3

SINIF İÇİ UYGULAMA KODLARI

Ders Tanıtım Sunumu. Database Managegement II. Elbistan Meslek Yüksek Okulu Güz Yarıyılı. Öğr. Gör. Murat KEÇECĠOĞLU

Java 2 Standart Edition SDK Kurulum ve Java ya Giriş

Ders 4: Diziler (Arrays( Arrays) barisgokce.com

Data Structures Lab Güz

Yrd. Doç. Dr. Caner ÖZCAN

Sanal Ortamda Nesnelerin Haptic Kol ile Manipülasyonu. Sevcan AYTEKİN Alpaslan DUYSAK

MAT214 BİLGİSAYAR PROGRAMLAMA II DERSİ Ders 12: Grafik Kullanıcı Arayüzü (Graphical User Interface-GUI)

Görsel Programlama 1

Veri Yapıları Laboratuvarı

Örnek bir Algoritma. Örneğimiz bir insanın evden çıkıp işe giderken izleyeceği yolu ve işyerine girişinde ilk yapacaklarını tanımlamaktadır.

Yazılım Nedir? 2. Yazılımın Tarihçesi 3. Yazılım Grupları 4 Sistem Yazılımları 4 Kullanıcı Yazılımları 5. Yazılımın Önemi 6

CBÜ Teknoloji Fakültesi, Yazılım Mühendisliği. Nesneye Yönelik Programlama

MAT213 BİLGİSAYAR PROGRAMLAMA I DERSİ Ders 1: Programlamaya Giriş

Scratch 2.0 GOL OYUNU

NOT: Bazı donanımlar giriş hemde çıkış donanımıdır. HEM GİRİŞ- HEM ÇIKIŞ BİRİMİ OLAN DONANIMLAR SABİT DİSK HAFIZA KARTLARI FLASH BELLEK

ÖDEVLERİ SİSTEME YÜKLEME USULLERİ

BİYOMETRİK İRİS SINIFLANDIRMA SİSTEMLERİ

Bil101 Bilgisayar Yazılımı I. M. Erdem ÇORAPÇIOĞLU Bilgisayar Yüksek Mühendisi

WeldEYE. Kurulum Kılavuzu. İçindekiler

C# nedir,.net Framework nedir?

İNTERNET TABANLI PROGRAMLAMA- 3.ders

BM102 BİLGİSAYAR PROGRAMLAMA II LABORATUVAR UYGULAMALARI. 3Hafta

Bahar. BM 211 Programlama Dilleri 3 1

MMT 106 Teknik Fotoğrafçılık 3 Digital Görüntüleme

YZM 2105 Nesneye Yönelik Programlama

WEB KULLANICI KONTROLLERİ ve ANASAYFA KULLANMA(Master Page)

DORYA ROBOTİK. İçindekiler. Kitap Sayfa Sayısı: 80 Kitap Fiyatı: 24,00 TL

«BM364» Veritabanı Uygulamaları

Bilgi ve Olay Yönetim Sistemi

Lambda İfadeleri (Lambda Expressions)

Archive Player Divar Series. Kullanım kılavuzu

5S7 OYUN YAZIYORUM GENEL BAKIŞ A. PROJE - YILDIZ TOPLAYAN ÇOCUK

Muayene olmamış sekmesinde seçili hasta üzerinde sağ klik Randevu Kabul ile Açılan Randevu Kabul İşlemleri ekranından hasta randevusu kabul edilerek

Aynı tipten çok sayıda değişken topluluğudur. X Y Score1 Score2 (0) (1) (2)...

YZM 2105 Nesneye Yönelik Programlama

Analiz Raporu. Projenin amacının, konusunun, işlevinin ne olacağı, hangi yazılımlar kullanılacak gibi parametrelerin belirlenmesi.

AKINSOFT Tahsilex. Yardım Dosyası. Doküman Versiyon : Tarih : Sayfa-1. Copyright 2010 AKINSOFT

Görsel Programlama DERS 03. Görsel Programlama - Ders03/ 1

Zaman Ayarlayıcı İşlemler

Transkript:

Otistik Bireylere Kinect İle Davranış Öğretimi Hazırlayanlar Ahmet YILDIZ Yağmur SUBAKAN Dilek SAĞLAM 1

İçindekiler İçindekiler....2 Kinect Nedir?...3 Kinect İçin Donanımsal Gereksinimler...5 Kinect İçin Yazılımsal Gereksinimler...5 Kinect Sensör İskelet Sistemi...6 Kinect Sensör Çalışma Mantığı.....7 Kinect Uygulama Platformu........8 Kinect Sensör Uygulamaları........9 Tıp........9 Eğitim.......11 Oyun.....12 Projenin Amacı......13 Kodlar......14 Kaynakça......20 Kinect Nedir? Kinect(1), Microsoft tarafından 2010 yılında dünya piyasalarına Project Natal adı altında satışa sunulmuş en güncel görüntüleme sensörüdür. 1.Kinect Sensör Kinect in en temel özelliği insan vücudunun hareketlerini algılayıp, onları temassız bir şekilde bilgisayar ortamına aktarmasıdır. Bu özelliğinden ötürü tıp, eğitim, oyun vb. alanlarda büyük ilgi görmüştür. 2 3

Kinect in yapısını(2);kinect i en belirgin özelliği ön tarafında yer alan 3 adet göz olacaktır. Bu üç gözden sağ ve sol taraftakiler 3 boyutlu derinliği algılamakta kullanılan sensörler iken ortada yer alan göz ise RGB görüntü alabilen bir kameradır. 3 boyut verisi için kullanılan iki gözden soldaki lazer projeksiyonu ile veri toplarken, sağdaki ise kızıl ötesi ışınları toplamaktadır. 2.Kinect Cihaz Bileşenleri -RGB Kamera; 640*480 piksel, saniyede 30 kare veya 1280*960 piksel, saniyede 12 kare olmak üzere iki farklı renk çözünürlüğü sunmaktadır. -3 Boyutlu Derinlik Sensörü; 80*60 piksel, 320*240 piksel veya 640*480 piksel çözünürlükte saniyede 30 kare olmak üzere 3 farklı derinlik görüntüsünü, 16 bit derinlik bilgisiyle alınabilmektedir. Aynı anda 6 farklı kişiden yalnız ikisi üzerinde işlemlerini gerçekleştirebilmektedir. -Mikrofon Grubunda; cihazın alt tarafına yerleştirilmiş 4 adet mikrofon dizisi bulunmaktadır. 24 bitlik ses algılama bilgisiyle işlem yapılabilmektedir. İdeal ses algılama mesafesi ise 1 metre ve 3 metre arasında değişmektedir. -Motor Mekanizması; alt kısmında bulunan DC motor yardımıyla + / - 27 derece dikey hareket kabiliyetine sahiptir. Kinect İçin Donanımsal Gereksinimler -32 bit (x86) veya 64 bit (x64) işlemci, -Çift çekirdek 2.66 GHz veya üzeri işlemci, -2 GB hafıza, -USB 2.0 veri yolu, -USB/Güç Kaynağı adaptörü bulunan bir Kinect sensör. Kinect İçin Yazılımsal Gereksinimler -Visual Studio 2010 Express veya üzeri sürümleri -.Net Framework 4.0 -Microsoft Speech Platform- Server Runtime 10.2 (x86 sürümü) -Microsoft Speech Platform- Software Development Kit 10.2 (x86 sürümü) 4 5

Kinect Sensör İskelet Sistemi Kinect, sensorları vasıtasıyla gelen bilgiler sayesinden bir insanın 3 boyutlu olarak hareketlerini yakalayabilmekte, yüzünü ve sesini tanımlayabilmektedir. Bu bilgiler sayesinde aynı anda 6 kişiyi takip edebilen Kinect, bu 6 kişi içerisinden ise aynı anda sadece ikisi üzerinde hareket analizi yapabilmekte ve bu iki kişinin her birinin vücudundaki 20 kesişim noktasına ait bilgileri verebilmektedir. Kinect tarafından takip edilebilen bu 20 kesişim noktasının nereler olduğunu aşağıdaki (3)Leonardo da Vinci nin Vitruvius Adamı (Vitruvian Man) üzerinde görebilirsiniz; Kinect Sensörün Çalışma Mantığı Kinect, üzerinde 3 Boyutlu derinlik sensörüyle 47 derece dikey ve 57 derece yatay alanda etrafını tarayarak bulunan cisimlerin uzaklıklarını hesaplamaktadır. Sensör, görüş açısına sürekli lazer ışını gönderir ve ışığın yansıma hızını hesaplayarak derinlik görüntüsüne ulaşmaktadır. Bu görüntüde yakaladığı en basit insan şekline ise içerisinde bulundurduğu görüntü işleme algoritmasıyla bir iskelet sistemi yerleştirmektedir. Kinect, bir kişiye ait 20 eklem noktasını X, Y ve Z koordinatlarını bilgisayar ortamına aktarmaktadır. Aynı anda 6 kişiyi algılayabilen sensör bunlardan yalnızca 2 tanesinin bilgisini işleyebilmektedir. Kinect in iskelet algılamasındaki önemli hususlardan biri ise en etkin ve doğru ölçümleri algılamasını 1, 2 metre ile 3, 5 metre mesafesinde yapabilmesidir. 6 7

Kinect Uygulama Platformu Kinect in üzerinde bulunan Mikrofon Grubu ve 3 Boyutlu Derinlik sensörleriyle algıladığı verileri ses, görüntü ve derinlik akışı verilerini yorumlamak üzere Doğal Kullanıcı Arayüzü kütüphanesine iletmektedir. Burada yorumlanan veriler ise uygulamalara bir komut olarak iletilerek program akışı sağlanmaktadır. Veri akışı Şekil 4 de gösterilmektedir. Kinect Sensörün Uygulamaları Hareket temelli işlemleri gerçekleştirebilen teknolojilerden biri de Kinect sensörüdür. Kinect cihazından bugün tıp, eğitim ve oyun gibi vb. birçok alanda yararlanılmaktadır. Bu alanlar için birçok uygulama geliştirilmektedir. Bu uygulamalar sayesinde kullanıcılar uygulama ile daha aktif bir iletişime geçmektedir. - Kinect ile Tıp Alanında Uygulama Hareket temelli işlemler teknolojisinden yararlanılabilecek ve uygulamalar geliştirilecek alanların en başında tıp gelmektedir. İnsan vücudu hareketlerinin temassız bir şekilde algılanması sayesinde tıp alanında birçok uygulama geliştirilmesine olanak sağlamıştır. 4. Bilgi Akış Yönü 8 9

Ameliyat esnasında sağlık personelinin, hastanın MR veya CT görüntülerini bilgisayar ortamında tekrar incelemek istediğinde aşağıdaki şekil-5 de görüldüğü üzere hem hijyen hem de zaman açısından avantaj oluşturmaktadır. - Kinect ile Eğitim Alanında Uygulama 5. Kinect ile Kalp Ritimlerinin Ölçümü Bugün, Kinect bu dezavantajları ortadan kaldırmaktadır. Temassız, insan vücudu hareketi sayesinde incelenecek görüntüler el hareketleriyle yönlendirilebilmektedir. Kinect ten fiziksel rehabilitasyon sürecinde de yararlanılmıştır. Yapılan bir çalışmada iki genç yetişkinin rehabilete olasılıkları 10 6. Kinect ile Eğitim Öğrenmedeki verimliliği ve kalıcılığı sağlamak için daha çok duyu organını öğrenme sürecin dahil etmek gerekmektedir. Kinect, bilginin anlamlandırılarak çeşitli yollarla sunulması ve kazanılmasına imkan sağlamaktadır. İnsan vücudu hareketleriyle gerçekleştirilen uygulamalar, öğrencilerin hem eğlenerek öğrenmesi hem de öğrenmedeki motivasyonlarının artırılması sağlanabilir. Kinect in eğitim materyalleri arasındaki yerini hızlı bir şekilde alması yukarıda şekil-6 da görüldüğü üzere,birçok eğitim kurumunun hareket temelli teknolojik eğitim ortamları oluşmasına sebep olmaktadır. 11

- Kinect ile Oyun Alanında Uygulama Günümüzdeki oyunlardaki etkileşimi artırmak adına insan vücudu hareketinden yararlanılmıştır. Oyun içerisinde vücut hareketlerinin algılanıp değerlendirilmesi açısından diğer oyun uygulamalarına göre ön plana çıkmaktadır. (7) Oyun uygulamalarında önemli bir yapı olan 3 Boyutlu görselleştirme Kinect in derinlik sensörleri tarafından sağlanabilmektedir. Bu sayede oyun içerisinde kullanıcı vücut hareketlerinin tamamını 3 boyutlu görsel bir yapının içerisinde gerçekleştirebilmektedir. Projenin Amacı Yapılan projenin amacı otistik bireylerin psiko-motor beceri gerektiren davranışları kazanmaları ve psiko-motor becerilerinde problem yaşayan bireylerin psiko-motor becerilerini geliştirmeleridir. Bireyler ekrandan modeli izleyerek adımları takip edecekler, modelin hareketlerini yapmaya çalışacaklardır. Bireylerin bu süreçte model ile dikkatleri çekilecektir. Otistik bireyler söylenenleri anlamayabilirler. Bu proje ile bireyler yapmaları gerekenleri görecekler ve duyma problemlerinden kaynaklanan anlama sıkıntıları ile karşılaşmayacaklardır. 12 13

Otistik Bireyler İçin Kinect İle Davranış Öğretimi Yapılan proje ile otistik bireylere diş fırçalamayı öğreten bir uygulama geliştirildi. Proje geliştirilmeye açıktır ve ilerleyen zamanlarda geliştirilecektir. Projenin genel olarak çalışma mantığı şu şekildedir: Kullanıcı arayüzü 4 parçadan oluşmaktadır. Ekranın solunda kullanıcının iskelet tanımlaması, sağ üstte hareketleri yapan, kullanıcıya örnek olacak iskelet videosu, sağ ortada kamera görüntüsü ve sağ altta derinlik görüntüsü yer almaktadır. Videodaki hareket görüntüleri kod ile tanımlanan iskelet karşısına geçilerek Kinect Studio ile kaydedilmiştir ve video halinde yayınlanmaktadır. Kullanıcı sensörün karşısına geçerek algılanacak ve ekranda gördüğü hareketleri yapacaktır. Proje görsel olarak dikkat çekmektedir ve hareketleri daha kolay yapabilmelerini sağlayacaktır. Temel olarak projede önemli olan eklemlerin hareketleridir. Projede ilk yapılması gereken Kinect SDK yı kurmaktır. Kurulumlar gerçekleştirdikten sonra Visual Studio nun açılması gerekmektedir. Projede 1.6 SDK ve Visual Studio 2015 kullanılmıştır. Visual Studio açıldıktan sonra New Project seçeneğine tıklıyoruz ve gelen ekranda WPF yi seçiyoruz. WPF kullanıcı arayüzü oluşturma platformudur. Kinect ile geliştirilen projeler genellikle WPF kullanılarak hazırlanır. 8. WPF Kullanıcı Arayüzü 14 15

-Projenin Kodlama Kısmı Kinect in kendine ait özel kütüphaneleri vardır. Elemanlara, metodlara erişebilmek için geliştirilen uygulamaya göre ilgili kütüphanenin eklenmesi gerekir. Yapılan projede Microsoft.Kinect.dll kütüphanesi kullanıldı. Kütüphanenizi açılan projenizde Project sekmesinden, Add Reference seçeneğini seçerek Browse bölümünden, dll inizin bulunduğu yere giderek ekleyebilirsiniz. Kütüphaneyi projede kullanabilmek için ekledikten sonra metodlara erişebilmek için birde using satırlarını eklenmesi gerekmektedir. Projede using Microsof.Kinect; satırı kullanılmıştır. Projeyi oluşturacak kodları oluştururken ilk öncelikle kullanıcı arayüzünü 4 parçaya bölündü. Bir Grid in içerisinde 3 adet İmage, 1 adette video için MediaElement eklendi. Kodlarımız ile birlikte ekran 4 parçaya bölünmüş oldu. Grid in içerisindeki her bir alan için yapılacaklar kodlandı. Kodlar aşağıdaki gibidir. 9. dll ekleme 16 17

<Window x:class= kamera.mainwindow xmlns= http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x= http://schemas.microsoft.com/winfx/2006/xaml xmlns:d= http://schemas.microsoft.com/expression/blend/2008 xmlns:mc= http://schemas.openxmlformats.org/markup-compatibility/2006 xmlns:local= clr-namespace:kamera mc:ignorable= d Title= Kinect Height= 700 Width= 700 WindowStartupLocati on= CenterScreen Loaded= Window_Loaded Closing= Window_Closing > <Grid Name= a Width= 700 Margin= 0,0,-8,-21 > <Image Name= imgcolorframe Stretch= Uniform Margin= 0,221,10,0 Height= 235 HorizontalAlignment= Right Width= 373 VerticalAlignment= Top /> <Image Name= imgdepthframe Stretch= Uniform Margin= 0,461,10,24 HorizontalAlignment= Right Width= 373 /> <Image Name= Skeleton1 Stretch= Uniform Margin= 12,1,0,0 Height= 665 HorizontalAlignment= Left Width= 300 VerticalAlignment= Top /> <MediaElement Name= mediaelement Source= disfircalama. mp4 LoadedBehavior= Manual HorizontalAlignment= Left Height= 174 Margin= 410,10,0,0 VerticalAlignment= Top Width= 280 /> <Button x:name= oynat Content= Oynat HorizontalAlignment= Left Margin= 452,196,0,0 VerticalAlignment= Top Width= 198 Height= 25 Click= oynat_click /> </Grid> </Window> 18 Kodlarımız ile birlikte ekranımız 4 parçaya bölündü. Kodlar içerisinde yer alan buton videoyu oynatmak içindir. Bu kısmı daha sonra iskelet tanımlamasından sonra ekleyebilirsiniz. Çünkü bu adımda henüz videomuz hazır değil. İlk önce iskeleti tanımlamamız gerekiyor. İskeletin tanımlanabilmesi için tanımlananlar: Sensörden gelen iskelet bilgisini tutacak olan Skeleton türünde bir dizi, gelen bilgilere göre iskeletin eklem bilgilerini tutacak olan Joint türünde bir dizi, eklemler dizisinde işlem yaptırılmak üzere kullanılacak bir iskelet değişkeni ve eklemlerimizi çizerek iskeleti oluşturmak için Line türünde bir List. Bu tanımlamalardan sonra iskeletin çizilebilmesi için program çalıştığında gelen iskelet veri akışına göre gelen bilgiyi işleyecek metot tetiklenmeli ve ilgili metota yönlendirilmelidir. Ayrıca iskeleti oluşturacak 18 adet çizgi (line) List e eklenmelidir. List e eklenen bu çizgiler daha sonra gelen bilginin işlenmesi ile verilen koordinatlara göre çizilmelidir. Çizilmeden önce işlenen bilgiye göre eklemler, eklemleri tutacak diziye eklenmeli ve buna göre çizgileri oluşturacak metot işlemi yapmalıdır. İşlemler bittikten sonra görüntü(iskelet) Grid e aktarılmalıdır ki kullanıcı görebilsin. Kodlar aşağıdaki gibidir. 19

public partial class MainWindow : Window private Skeleton[] iskeletler = new Skeleton[0]; // iskelet bilgisini tutacak dizi private Skeleton iskelet; // iskelet çizerken üzerinde işlem yapılacak değişken private int sayac = 0; // çizgi sayısını tutacak ve çizdikçe artacak değişken private Joint[,] dizi = new Joint[19, 2]; // eklem bilgilerini tutacak matris dizisi private List<Line> liste = new List<Line>(); // eklemleri çizecek Line türündeki List public MainWindow() InitializeComponent(); this.loaded += new RoutedEventHandler(Window_Loaded); private WriteableBitmap skeletongiris=null; // çizilen iskeleti İmage in içine aktarmak için kullanılacak. Bu değer ilk önce her zaman null atanmalıdır. Null olduğunu belirtmezseniz hata vermez programınız çalışır fakat uyarı olarak görünür. (başımıza geldi de :) ) private void Window_Loaded(object sender, RoutedEventArgs e) if (KinectSensor.KinectSensors.Count > 0) // sensör bağlı ise KinectSensor.KinectSensors[0].Start(); // sensörü başlat KinectSensor.KinectSensors[0].SkeletonStream.Enable(); // iskelet veri akışını aktifleştir. KinectSensor.KinectSensors[0].SkeletonFrameReady += new Eve nthandler<skeletonframereadyeventargs>(mainwindow_skeletonframeready); // akıştan gelen bilginin işlenmesi için ilgili metodu tetikle for (int i = 0; i < 18; i++) // 18 adet çizgi çizecek ve her bir çizgiyi List e ekleyecek Line line = new Line(); liste.add(line); 20 void MainWindow_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) using (SkeletonFrame skeletonframe = e.openskeletonframe()) //Gelen bilgiyi açıp skeletonframe e aktar if (skeletonframe!= null) // akış boş değil ise iskeletler = new Skeleton[skeletonFrame.SkeletonArrayLength]; // dizinin uzunluğunu gelen akışa göre uzat skeletonframe.copyskeletondatato(iskeletler); // iskeletler dizisine kopyala foreach (Skeleton skel in iskeletler) // verileri sırala if (skel.trackingstate == SkeletonTrackingState.Tracked) // veriler izlenen veri ile eşitse iskelet = skel; // verileri iskelet değişkenine ata this.diziyeeklemekle(iskelet); 21

private void DiziyeEklemEkle(Skeleton iskelet) // gövdeyi çizmek için eklem bilgileri dizi[0, 0] = iskelet.joints[jointtype.head]; dizi[0, 1] = iskelet.joints[jointtype.shouldercenter]; dizi[1, 0] = iskelet.joints[jointtype.shouldercenter]; dizi[1, 1] = iskelet.joints[jointtype.shoulderleft]; dizi[2, 0] = iskelet.joints[jointtype.shouldercenter]; dizi[2, 1] = iskelet.joints[jointtype.shoulderright]; dizi[3, 0] = iskelet.joints[jointtype.shouldercenter]; dizi[3, 1] = iskelet.joints[jointtype.spine]; dizi[4, 0] = iskelet.joints[jointtype.spine]; dizi[4, 1] = iskelet.joints[jointtype.hipcenter]; dizi[5, 0] = iskelet.joints[jointtype.hipcenter]; dizi[5, 1] = iskelet.joints[jointtype.hipleft]; dizi[6, 0] = iskelet.joints[jointtype.hipcenter]; dizi[6, 1] = iskelet.joints[jointtype.hipright]; // sol kolu çizmek için eklem bilgileri dizi[7, 0] = iskelet.joints[jointtype.shoulderleft]; dizi[7, 1] = iskelet.joints[jointtype.elbowleft]; dizi[8, 0] =iskelet.joints[jointtype.elbowleft]; dizi[8, 1] = iskelet.joints[jointtype.wristleft]; dizi[9, 0] = iskelet.joints[jointtype.wristleft]; dizi[9, 1] = iskelet.joints[jointtype.handleft]; // sağ kolu çizmek için eklem bilgileri dizi[10, 0] = iskelet.joints[jointtype.shoulderright]; dizi[10, 1] = iskelet.joints[jointtype.elbowright]; dizi[11, 0] = iskelet.joints[jointtype.elbowright]; dizi[11, 1] = iskelet.joints[jointtype.wristright]; dizi[12, 0] = iskelet.joints[jointtype.wristright]; dizi[12, 1] = iskelet.joints[jointtype.handright]; Devamı -> // sol bacağı çizmek için eklem bilgileri dizi[13, 0] =iskelet.joints[jointtype.hipleft]; dizi[13, 1] = iskelet.joints[jointtype.kneeleft]; dizi[14, 0] = iskelet.joints[jointtype.kneeleft]; dizi[14, 1] = iskelet.joints[jointtype.ankleleft]; dizi[15, 0] = iskelet.joints[jointtype.ankleleft]; dizi[15, 1] = iskelet.joints[jointtype.footleft]; // sağ ayağı çizmek için eklem bilgileri dizi[16, 0] = iskelet.joints[jointtype.hipright]; dizi[16, 1] =iskelet.joints[jointtype.kneeright]; dizi[17, 0] = iskelet.joints[jointtype.kneeright]; dizi[17, 1] = iskelet.joints[jointtype.ankleright]; dizi[18, 0] = iskelet.joints[jointtype.ankleright]; dizi[18, 1] = iskelet.joints[jointtype.footright]; Ciz(); private void Ciz() for (int i = 0; i < 18; i++) liste[i].strokethickness = 8; // çizgilerin kalınlığı liste[i].stroke = System.Windows.Media.Brushes.Black; //çizgi rengi // çizgilerin koordinatları liste[i].x1 = (dizi[i, 0].Position.X + 1) * 100; liste[i].x2 = (dizi[i, 1].Position.X + 1) * 100; liste[i].y1 = 480 - (dizi[i, 0].Position.Y + 1) * 220; liste[i].y2 = 480 - (dizi[i, 1].Position.Y + 1) * 220; NOT: Koordinatları iskeletin yer alacağı bölgenin boyutuna göre ayarlamanız gerekmektedir. if (sayac < 18) a.children.add(liste[i]); // çizgileri gride ekle sayac++; Skeleton1.Source = skeletongiris; // skeleton image inde görünmesi için kaynak ver 22 23

Bu aşamadan sonra video çekildi. Sensörün karşısına geçerek yapılması gereken hareketler yapıldı ve bu sırada hareketler kayıt edildi. Kaydedilen videonun MediaElement içerisinde yolu gösterildi ve oynatma işlemi manuel yapılarak kullanıcının yeniden oynatabilmesi sağlandı. Bunun için MediaElement in başlangıç olayı manuel yapıldı. Kodlar aşağıdaki gibidir. private void Window_Loaded(object sender, RoutedEventArgs e) mediaelement.play();...// daha önce verilen kodlar yer alır. private void oynat_click(object sender, RoutedEventArgs e) mediaelement.stop(); mediaelement.play(); Bu aşamadan sonra kamera görüntüsü oluşturulması gerekmektedir. Kodlamalar ile sensörün görüş açısındaki her şey normal kameralardaki gibi görünecektir. Buradaki mantık şudur: Görüntü geldiğinde görüntü işlemek için kullanılan metot tetiklenecek. Gelen görüntü bilgisi alınacak ve ilk önce programda daha önceden belirtilen format ile karşılaştırılarak boyutlarına bakılacak. Biz tanımsız yaptık. Bu nedenle formatlar ilk program çalıştığında farklı olacaktır. Daha sonra gelen tüm görüntü bilgileri aynı formatta olursa akışın sürekliliği sağlanacak ve hatasız ilerleyecektir. Formatların farklılığı durumunda ilk önce yeni görüntü bilgileri diziye aktarılacak daha sonra görüntü için ayrılan alana göre genişlik ve yükseklik ayarı yapılacaktır. Bu işlemlerden sonra görüntü kullanıcıya aktarılacaktır. Kodlar aşağıdaki gibidir. 24 25

private byte[] pixeldata; // görüntü akışını tutacak byte dizisi private WriteableBitmap cikisresmi; // işlenen akışı image e aktarmak için kullanılacak private ColorImageFormat eskirenkformati = ColorImageFormat.Undefined; // gelen akışın boyut değişikliğini algılayabilmek için yeni format ve eski format arasında karşılaştırma yapılacak. Şuan eski format tanımsız private void Window_Loaded(object sender, RoutedEventArgs e) if (KinectSensor.KinectSensors.Count > 0) KinectSensor.KinectSensors[0].Start(); KinectSensor.KinectSensors[0].ColorStream. Enable(ColorImageFormat.RgbResolution1280x960Fps12); // görüntü akışını başlat KinectSensor.KinectSensors[0].ColorFrameReady += new Event Handler<ColorImageFrameReadyEventArgs>(Kinect_ColorFrameReady); // akışın işlenebilmesi için ilgili metodu tetikle imageframe.copypixeldatato(pixeldata); // diziye kopyala if (havenewformat) // farklı ise cikisresmi = new WriteableBitmap(imageFrame.Width, image- Frame.Height, 105, 96, PixelFormats.Bgr32, null); // kullanıcıya görüntülenecek görüntünün boyutları ayarlandı. (Bu kısımda siz kullanacağınız ekran genişliğine göre width ve height değerlerinde oynama yapabilirsiniz.) imgcolorframe.source = cikisresmi; // imgcolorframe image inde görünebilmesi için kaynak ver cikisresmi.writepixels(new Int32Rect(0, 0, imageframe.width, imageframe.height),pixeldata,imageframe.width * 4,0); // görüntü akışının sürekliliği için içeriği güncelle eskirenkformati = imageframe.format; // yukarıda açıklandığı gibi boyutlarda hata olmaması için karşılaştırma yapmak amacıyla yeni formatı kaydet private void Kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) using (ColorImageFrame imageframe = e.opencolorimageframe()) if (imageframe!= null) bool havenewformat = eskirenkformati!= imageframe.format; // yeni görüntü formatı ile önceki görüntü formatı farklı mı? if (havenewformat) // farklı ise pixeldata = new byte[imageframe.pixeldatalength]; // pixeldata dizisinin uzunluğunu yeni gelen akışa göre uzat 26 27

Son aşama olarak derinlik bilgisi için kodlamalar yapılmaktadır. Derinlik görüntüsü işlenirken aslında kamera görüntüsü alırken yapılan adımlardan farklı bir şey yapmamaktadır. Her ikisi de aynı mantık ve sıralama ile kodlanmaktadır fakat her birinin kendine özgü metotları ve elemanları var. Örneğin derinlik için DepthImageFrame, kamera için ColorImageFrame kullanılır. Kodlar aşağıdaki gibidir. private short[] depthpixeldata; // derinlik bilgisini tutacak olan dizi private WriteableBitmap cikisderinlik; private DepthImageFormat eskiderinlikformati = DepthImage- Format.Undefined; private void Window_Loaded(object sender, RoutedEventArgs e) mediaelement.play(); if (KinectSensor.KinectSensors.Count > 0) KinectSensor.KinectSensors[0].Start(); KinectSensor.KinectSensors[0].DepthStream. Enable(DepthImageFormat.Resolution640x480Fps30); // derinlik akışını başlat KinectSensor.KinectSensors[0].DepthFrameReady += new Eve nthandler<depthimageframereadyeventargs>(kinect_depth- FrameReady); // akışın işlenebilmesi için ilgili metodu tetikle 28 private void Kinect_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e) using (DepthImageFrame depthframe = e.opendepthimageframe()) // Gelen derinlik bilgisini açıp depthframe e aktar if (depthframe!= null) bool havenewformat = eskiderinlikformati!= depthframe. Format; if (havenewformat) depthpixeldata = new short[depthframe.pixeldatalength]; // gelen akışın uzunluğuna göre dizinin uzunluğunu uzat depthframe.copypixeldatato(depthpixeldata); //diziye kopyala if (havenewformat) cikisderinlik = new WriteableBitmap(depthFrame. Width,depthFrame.Height,85, 96, PixelFormats.Gray16, null); // kullanıcının göreceği boyut ayarlandı imgdepthframe.source = cikisderinlik; cikisderinlik.writepixels(new Int32Rect(0, 0, depthframe. Width, depthframe.height),depthpixeldata,depthframe.width * depthframe.bytesperpixel,0); eskiderinlikformati = depthframe.format; 29

Kodlarımızı bitirdik. Projenin tüm kodları toplu olarak aşağıda vermiştir. 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 kamera /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window private Skeleton[] iskeletler = new Skeleton[0]; private Skeleton iskelet; private int sayac = 0; private Joint[,] dizi = new Joint[19, 2]; private List<Line> liste = new List<Line>(); public MainWindow() InitializeComponent(); this.loaded += new RoutedEventHandler(Window_Loaded); public MainWindow() InitializeComponent(); this.loaded += new RoutedEventHandler(Window_Loaded); private byte[] pixeldata; private WriteableBitmap cikisresmi; private short[] depthpixeldata; private WriteableBitmap cikisderinlik; private WriteableBitmap skeletongiris=null; private DepthImageFormat eskiderinlikformati = DepthImage- Format.Undefined; private ColorImageFormat eskirenkformati = ColorImageFormat.Undefined; private void Window_Loaded(object sender, RoutedEventArgs e) mediaelement.play(); if (KinectSensor.KinectSensors.Count > 0) KinectSensor.KinectSensors[0].Start(); KinectSensor.KinectSensors[0].ColorStream. Enable(ColorImageFormat.RgbResolution1280x960Fps12); KinectSensor.KinectSensors[0].ColorFrameReady += new Event Handler<ColorImageFrameReadyEventArgs>(Kinect_ColorFrameReady); KinectSensor.KinectSensors[0].SkeletonStream.Enable(); KinectSensor.KinectSensors[0].SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(MainWind ow_skeletonframeready); 30 31

KinectSensor.KinectSensors[0].DepthFrameReady += new Event Handler<DepthImageFrameReadyEventArgs>(Kinect_DepthFrameReady); KinectSensor.KinectSensors[0].DepthStream. Enable(DepthImageFormat.Resolution640x480Fps30); for (int i = 0; i < 18; i++) Line line = new Line(); liste.add(line); void MainWindow_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) using (SkeletonFrame skeletonframe = e.openskeletonframe()) if (skeletonframe!= null) iskeletler = new Skeleton[skeletonFrame.SkeletonArrayLength]; skeletonframe.copyskeletondatato(iskeletler); foreach (Skeleton skel in iskeletler) if (skel.trackingstate == SkeletonTrackingState.Tracked) iskelet = skel; this.diziyeeklemekle(iskelet); private void DiziyeEklemEkle(Skeleton iskelet) dizi[0, 0] = iskelet.joints[jointtype.head]; dizi[0, 1] = iskelet.joints[jointtype.shouldercenter]; dizi[1, 0] = iskelet.joints[jointtype.shouldercenter]; dizi[1, 1] = iskelet.joints[jointtype.shoulderleft]; dizi[2, 0] = iskelet.joints[jointtype.shouldercenter]; dizi[2, 1] = iskelet.joints[jointtype.shoulderright]; dizi[3, 0] = iskelet.joints[jointtype.shouldercenter]; dizi[3, 1] = iskelet.joints[jointtype.spine]; dizi[4, 0] = iskelet.joints[jointtype.spine]; dizi[4, 1] = iskelet.joints[jointtype.hipcenter]; dizi[5, 0] = iskelet.joints[jointtype.hipcenter]; dizi[5, 1] = iskelet.joints[jointtype.hipleft]; dizi[6, 0] = iskelet.joints[jointtype.hipcenter]; dizi[6, 1] = iskelet.joints[jointtype.hipright]; dizi[7, 0] = iskelet.joints[jointtype.shoulderleft]; dizi[7, 1] = iskelet.joints[jointtype.elbowleft]; dizi[8, 0] = iskelet.joints[jointtype.elbowleft]; dizi[8, 1] = iskelet.joints[jointtype.wristleft]; dizi[9, 0] = iskelet.joints[jointtype.wristleft]; dizi[9, 1] = iskelet.joints[jointtype.handleft]; dizi[10, 0] = iskelet.joints[jointtype.shoulderright]; dizi[10, 1] = iskelet.joints[jointtype.elbowright]; dizi[11, 0] = iskelet.joints[jointtype.elbowright]; dizi[11, 1] = iskelet.joints[jointtype.wristright]; dizi[12, 0] = iskelet.joints[jointtype.wristright]; dizi[12, 1] = iskelet.joints[jointtype.handright]; dizi[13, 0] = iskelet.joints[jointtype.hipleft]; dizi[13, 1] = iskelet.joints[jointtype.kneeleft]; dizi[14, 0] = iskelet.joints[jointtype.kneeleft]; dizi[14, 1] = iskelet.joints[jointtype.ankleleft]; 32 33

dizi[15, 0] = iskelet.joints[jointtype.ankleleft]; dizi[15, 1] = iskelet.joints[jointtype.footleft]; dizi[16, 0] = iskelet.joints[jointtype.hipright]; dizi[16, 1] = iskelet.joints[jointtype.kneeright]; dizi[17, 0] = iskelet.joints[jointtype.kneeright]; dizi[17, 1] = iskelet.joints[jointtype.ankleright]; dizi[18, 0] = iskelet.joints[jointtype.ankleright]; dizi[18, 1] = iskelet.joints[jointtype.footright]; Ciz(); private void Ciz() for (int i = 0; i < 18; i++) liste[i].strokethickness = 8; liste[i].stroke = System.Windows.Media.Brushes.Black; liste[i].x1 = (dizi[i, 0].Position.X + 1) * 100; liste[i].x2 = (dizi[i, 1].Position.X + 1) * 100; liste[i].y1 = 480 - (dizi[i, 0].Position.Y + 1) * 220; liste[i].y2 = 480 - (dizi[i, 1].Position.Y + 1) * 220; if (sayac < 18) a.children.add(liste[i]); sayac++; Skeleton1.Source = skeletongiris; private void Kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) using (ColorImageFrame imageframe = e.opencolorimageframe()) if (imageframe!= null) bool havenewformat = eskirenkformati!= imageframe.format; 34 if (havenewformat) pixeldata = new byte[imageframe.pixeldatalength]; imageframe.copypixeldatato(pixeldata); if (havenewformat) cikisresmi = new WriteableBitmap(imageFrame.Width, image- Frame.Height, 105, 96, PixelFormats.Bgr32, null); imgcolorframe.source = cikisresmi; cikisresmi.writepixels(new Int32Rect(0, 0, imageframe. Width, imageframe.height),pixeldata,imageframe.width * 4,0); eskirenkformati = imageframe.format; private void Kinect_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e) using (DepthImageFrame depthframe = e.opendepthimageframe()) if (depthframe!= null) bool havenewformat = eskiderinlikformati!= depthframe. Format; if (havenewformat) depthpixeldata = new short[depthframe.pixeldatalength]; depthframe.copypixeldatato(depthpixeldata); 35

if (havenewformat) cikisderinlik = new WriteableBitmap(depthFrame. Width,depthFrame.Height,85, 96, PixelFormats.Gray16, null); imgdepthframe.source = cikisderinlik; cikisderinlik.writepixels(new Int32Rect(0, 0, depthframe. Width, depthframe.height),depthpixeldata,depthframe.width * depthframe.bytesperpixel,0); eskiderinlikformati = depthframe.format; private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) Tüm bu aşamalar tamamlandıktan sonra Kinect sensörün bilgisayara takılı olduğundan emin olup program başlatıldığında projenin çalışan hali görülecektir. Not: Kinect sensörün bilgisayara takılabilmesi için adaptör almanız gerekmektedir. Sensörün girişi bilgisayara uygun değildir. Adaptör ile bilgisayara uyumlu hale gelecektir. if (KinectSensor.KinectSensors.Count > 0) foreach (KinectSensor sensor in KinectSensor.KinectSensors) sensor.stop(); private void oynat_click(object sender, RoutedEventArgs e) mediaelement.stop(); mediaelement.play(); 36 37

Kaynakça -http://ab.org.tr/ab13/bildiri/258.pdf -http://www.enterprisecoding.com/post/windows-icin-kinect-sdk -http://www.tekdozdijital.com/yenixbox-one-ve-kinectin-tele-tip-alanindakimuhtemel-kullanimi.html -http://www.jumpido.com/en/education/kinect/school/case-studies/sofia137 -http://mehmetulucanozelegitim.meb.k12. tr/icerikler/okulumuza-microsoft-destegi-ile-xbox-kinect-oyun-konsolu-kuruldu_1964957.html 10. Programın Çıktısı 38 39