Facebook RSS Feed
 
Kinect & Leap Motion: Kinect 102: Renkli Görüntüye Ulaşım
Tarih: 17.07.2012, Platform: .NET 4.0, IDE: Visual Studio 2010, Level: 100



Kinect'in RGB görüntü sensörü, uygulamalarımızda renkli görüntü kullanabilmemizi sağlar. Kinect 102 çalışmamızda, farklı çözünürlüklerde renkli görüntüye ulaşım üzerinde duracağız.

Öngereksinimler

Kinect ile uygulama geliştirmek için, www.kinectforwindows.com adresinden Kinect SDK'yı indirip kurmanız gerekiyor. Temel bilgiler için önce Kinect 101 yazımıza göz atabilirsiniz.

Çalışma Mantığı

Kinect'in ortasında yer alan RGB görüntü sensörü, istenilen çözünürlükte sürekli fotoğraf çekerek uygulamamıza iletir. Bu sensör kamera olarak değil, hızlı bir fotoğraf makinesi olarak çalışır. Uygulama içerisinden görüntüye ulaşım süreci 4 adımda gerçekleşir:

1. "KinectSensor.KinectSensors[0].Start()" metodu ile Kinect başlatılır.
2. "ColorStream.Enable()" metodu ile istenilen çözünürlükte renkli fotoğraf çekim süreci başlatılır.
3. RGB görüntüsüne ulaşacağımız "ColorFrameReady" eventi oluşturulur.
4. Fotoğraf çekildikçe çözünürlüğe göre saniyede 12 ile 30 arasında "ColorFrameReady" eventi tetiklenir. Bu eventin argümanları aracılığıyla görüntüye ulaşılır.

Desteklenen Görüntü Biçimleri

Kinect, 4 farklı biçimde renkli görüntü sağlar:

- RGB 1280 x 960 piksel, saniyede 12 kare
- RGB 640 x 480 piksel, saniyede 30 kare
- Raw YUV 640 x 480 piksel, saniyede 15 kare
- YUV 640 x 480 piksel, saniyede 15 kare

Uygulama

İlk Kinect çalışmamızda, Image elementi içerisinde canlı RGB görüntü gösteren bir WPF uygulaması geliştireceğiz. Kinect uygulamalarında WPF kullanmamız, performans ve tasarım yönünden tercih sebebi olacaktır.

Yeni oluşturacağımız WPF uygulamamızın proje referanslarına "C:\Program Files\Microsoft SDKs\Kinect\v1.5\Assemblies" klasöründe yer alan "Microsoft.Kinect.dll" dosyasını ekleyelim. Bu referans ile Kinect'in özelliklerini uygulamamıza ekleyebileceğiz.

İlk aşamada, MainWindow'a bir image elementi ekleyeceğiz. Daha sonra, Kinect'in yakaladığı renkli görüntüyü image elementinin kaynağı olarak belirleyerek uygulamamızda gösterilmesini sağlayacağız.

Adım 1: Arayüz

MainWindow'umuzun Grid'i içerisine "imgColorFrame" isminde bir image elementi ekleyeceğiz ve Strech özelliğini isteğe bağlı "Uniform" olarak belirleyeceğiz.

MainWindow.xaml

<Window x:Class="Kinect102_RGB.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Kinect 102: RGB Görüntü" Height="522" Width="660"
        WindowStartupLocation="CenterScreen"
        Loaded="Window_Loaded" Closing="Window_Closing">
    <Grid>
        <Image Name="imgColorFrame" Stretch="Uniform" />
    </Grid>
</Window>

Bu ekleme ile aşağıdaki görüntüye ulaşıyoruz:

-

Adım 2: Uygulama Kodları

İkinci adımda, uygulamamızın görüntü yakalayan kodlarını ekleyeceğiz. MainWindow.cs dosyasının using statementları arasına "using Microsoft.Kinect;" satırını ekleyelim. Artık Kinect'e ait özelliklere "KinectSensor" sınıfından erişmeye hazırız.

Bir bilgisayara 4 Kinect sensör bağlayabiliyoruz. Her bir sensöre "KinectSensors" dizisinden ulaşılıyor. Örneğin, bilgisayarımıza bağlı ilk Kinect'e "KinectSensor.KinectSensors[0]" kodu ile erişebiliriz. Dilersek dizi indexi belirtmek yerine Kinect Device Connection ID yada Unique Kinect ID kullanarak istediğimiz Kinect cihazına erişebiliriz:
"KinectSensors.KinectSensor["USB\VID_XXXX&PID_XXXX\XXXXXXXXXXXXXX"]"

Uygulamamızı geliştirirken, öncelikle "Window_Loaded" eventi içerisinde Kinect’i başlatacağız. Daha sonra "EnableColorStream" metoduyla renkli görüntü akışını başlatacağız. İstediğimiz çözünürlüğü bu metodun parametresi olarak belirlemeliyiz. Devamında, "ColorStreamReady" eventini de oluşturarak uygulamamızı her görüntü yakalandığında event tetikleyecek şekilde yapılandırmış oluyoruz.

Bu aşamadan sonra, Kinect her fotoğraf çektiğinde "ColorStreamReady" eventi tetiklenecek ve argümanlar içerisinden görüntünün yer aldığı diziye ulaşabileceğiz. Basit bir kod bloğu ile bu diziyi Bitmap'e çevirip, image elementinin kaynağı olarak güncelleyeceğiz.

Uygulama kapanırken de "Window_Closing" eventi içerisinde Kinect'i durduracağız.

Uygulama kodlarımıza göz atalım:

[C#] MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Kinect;
 
namespace Kinect102_RGB
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        
        // Her bir noktanın renk değerlerini tutacak byte dizisi:
        private byte[] pixelData;
 
        // Image elementinin kaynağı olarak atanacak görüntü:
        private WriteableBitmap outputImage;
 
        // Görüntü biçimi değiştirilirse, pixelData ve outputImage boyutlarını da
        // değiştirmemiz gerekiyor. Performans açısından, her frame için boyutları
        // yeniden belirlemek yerine, son görüntü biçimiyle yeni görüntü biçimini
        // karşılaştırıyoruz. Yalnızca aralarında fark varsa boyutları değiştiriyoruz.
 
        // Karşılaştırmayı yapacağımız görüntü biçimi:
        private ColorImageFormat lastImageFormat = ColorImageFormat.Undefined;
        
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            #region Kinect Init
 
            // Kinect bağlıysa, belirtilen parametrelere göre ilk Kinect'i yapılandır:
            if (KinectSensor.KinectSensors.Count > 0)
            {
                // Sisteme bağlı Kinect'lere, KinectSensors dizisinden ulaşıyoruz.
                // İlk Kinect'i başlat:
                KinectSensor.KinectSensors[0].Start();
 
                // Kinect'in renkli görüntü akışını RGB 640x480 30fps biçiminde başlat:
                KinectSensor.KinectSensors[0].ColorStream.Enable
                    (ColorImageFormat.RgbResolution640x480Fps30);
                // Görüntü biçimini değiştirmek için, Color Image Format parametresini
                // değiştirebilirsiniz.
 
                // Yeni görüntü geldiğinde tetiklenecek eventi oluştur:
                KinectSensor.KinectSensors[0].ColorFrameReady
                    += new EventHandler<ColorImageFrameReadyEventArgs>(Kinect_ColorFrameReady);
            }
 
            #endregion
        }
 
        private void Kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            // Gelen görüntü bilgisini açıp imageFrame'e aktar:
            using (ColorImageFrame imageFrame = e.OpenColorImageFrame())
            {
                // Görüntü varsa:
                if (imageFrame != null)
                {
                    // Önceki görüntü biçimi ile yeni gelen görüntü biçimi farklı mı?
                    bool haveNewFormat = lastImageFormat != imageFrame.Format;
 
                    // Görüntü biçimi değiştiyse:
                    if (haveNewFormat)
                    {
                        // Yeni görüntü boyutuna göre pixelData dizisini boyutlandır:
                        pixelData = new byte[imageFrame.PixelDataLength];
                    }
 
                    // Görüntüyü pixelData dizisine aktar:
                    imageFrame.CopyPixelDataTo(pixelData);
 
                    // Görüntü biçimi değiştiyse:
                    if (haveNewFormat)
                    {
                        // Image elementinin kaynağı olarak gösterilen outputImage'ın
                        // özelliklerini değiştir:
                        outputImage = new WriteableBitmap(
                            imageFrame.Width,  // Genişlik
                            imageFrame.Height, // Yükseklik
                            96,  // Yatay DPI
                            96,  // Dikey DPI
                            PixelFormats.Bgr32, // Piksel biçimi
                            null); // Bitmap paleti
 
                        // Image elementinin kaynağını outputImage olarak belirle:
                        imgColorFrame.Source = outputImage;
                    }
 
                    // outputImage'ın içeriğini güncelle:
                    outputImage.WritePixels(
                        new Int32Rect(0, 0, imageFrame.Width, imageFrame.Height),
                        pixelData,
                        imageFrame.Width * 4,
                        0);
 
                    // Bir sonraki görüntü biçimi karşılaştırması için, yeni görüntü
                    // biçimini kaydet:
                    lastImageFormat = imageFrame.Format;
                }
            }
        }
 
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // Kinect(ler) sisteme bağlıysa:
            if (KinectSensor.KinectSensors.Count > 0)
            {
                // Tüm Kinect'leri durdur:
                foreach (KinectSensor sensor in KinectSensor.KinectSensors)
                    sensor.Stop();
            }
        }
    }
}

Uygulamayı çalıştırdığımızda, Kinect'den gelen RGB görüntüsünü image elementi içerisinde göreceğiz.

Kinect, bir USB Hub'ın büyük bir kısmını kullanır. Görüntüye ulaşamazsanız, Kinect'in bağlı olduğu hub'a bağlı diğer cihazları çıkarıp yeniden deneyin.


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

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