Makale Özeti

Bu makalemde sizlere Kinect ile sesli haberleşmeden bahsedeceğim.

Makale

Herkese merhaba,

Bu makalemde sizlere Kinect ile sesli haberleşmeden bahsedeceğim. Evet yanlış duymadınız!

Kinect sadece görsel algılama olarak değil ses algılamada da oldukça başarılı. Gelin Kinect’in bu yeteneğini örnek bir senaryomuz ile beraber inceleyelim. Senaryomuz şu şekilde:

Kullanıcı “red” dediğinde başlangıçta beyaz renkli olan elipsimiz kırmızı renkli, kullanıcı “yellow” dediğinde ise elipsimiz sarı renkli olacaktır. Bitti mi? Hayır :) Kinect ile sohbete ne dersiniz?? Evet, sohbet diyorum, yanlış duymadınız. :) Şimdi gelin bunların nasıl olduğuna geçelim…

İlk olarak seslerle ilgili işlemler yapabilmemiz için Microsoft Speech Platform SDK’sını sisteminize uygun versiyonunu buradan indirip kurmalısınız. Kurulum işlemi bittikten sonra  Microsoft Visual Studio’da bir WPF projesi oluşturuyoruz. Ardından projemize

using Microsoft.Kinect;
using Microsoft.Speech.AudioFormat;
using Microsoft.Speech.Recognition;
using System.IO;
using System.Threading;

referanslarımızı ekliyoruz.  “Microsoft.Speech.AudioFormat” ve“Microsoft.Speech.Recognition” referanslarını ekleyebilmek için “References –> Add Reference –> Browse” yolunu izleyerek az önce kurduğumuz Microsoft Speech Platform SDK’nı kurduğumuz yere gidiyoruz.

Bu işlemin ardından projemizi build ediyoruz. Ardından “MainWindow.xaml”  dosyamızın içeriğini aşağıdaki gibi hazırlıyoruz.

 

<Window x:Class="KinectSesKontrol.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" >
    <Grid>
        <Ellipse Height="32" HorizontalAlignment="Left" Margin="12,19,0,0" Name="ellipse1" Stroke="Black" VerticalAlignment="Top" Width="32" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="71,19,0,0" Name="txtblck1" VerticalAlignment="Top" />
        <TextBlock Height="23" HorizontalAlignment="Left" Margin="71,56,0,0" Name="txtblck2" VerticalAlignment="Top" />
        <RichTextBox Height="200" HorizontalAlignment="Left" Margin="12,99,0,0" Name="richTextBox1" VerticalAlignment="Top" Width="479" IsReadOnly="True" 
         VerticalScrollBarVisibility="Auto" />
    </Grid>
</Window>

“MainWindow.xaml.cs”  içerisinde global değişkenlerimizi tanımlıyoruz.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using Microsoft.Speech.AudioFormat;
using Microsoft.Speech.Recognition;
using System.IO;
using System.Threading;

namespace KinectSesKontrol
{    
    public partial class MainWindow : Window
    {        
        //Global Değişkenlerimiz//
        public KinectSensor sensor;        
        private SpeechRecognitionEngine speechRecognizer;        
        FlowDocument mcFlowDoc = new FlowDocument();
        private static RecognizerInfo GetKinectRecognizer()
        {
            Func<RecognizerInfo, bool> matchingFunc = r =>
            {
                string value;
                r.AdditionalInfo.TryGetValue("Kinect", out value);
                return "True".Equals(value, StringComparison.InvariantCultureIgnoreCase) && "en-US".Equals(r.Culture.Name, StringComparison.InvariantCultureIgnoreCase);
            };
            return SpeechRecognitionEngine.InstalledRecognizers().Where(matchingFunc).FirstOrDefault();
        }
        //Global Değişkenlerimiz//

Programımız çalışmaya başladığında yapılması gerekenleri kodluyoruz.

 public MainWindow()
        {
            InitializeComponent();
            KinectCalistir();           
        }

        private void KinectCalistir()
        {            
            if(KinectSensor.KinectSensors.Count>0)
            {
                sensor=KinectSensor.KinectSensors[0];
                sensor.Start();
            }
            speechRecognizer = Tanimlama();
            Duy();          
        }

Ardından gelecek olan ses verilerinin özelliklerini tanımlayalım.

private void Duy()
        {            
            var audioSource =sensor.AudioSource;
            //Gelecek olan sesleri uyarlamalı modda kabul ediyoruz
            audioSource.BeamAngleMode = BeamAngleMode.Adaptive;
            //kinectten ses algılamaya başlayalım 
            var kinectStream = audioSource.Start();
            //Sesimizin özelliklerini tanımlayalım
            speechRecognizer.SetInputToAudioStream(
                kinectStream, new SpeechAudioFormatInfo(EncodingFormat.Pcm, 16000, 16, 1, 32000, 2, null));
            //"Multiple" seçerek grammerimizde bulunan herhangi bir kelime ile eşleşme olduğunda dinlemeye devam etmesini sağlamış oluyoruz.
            //"Single" seçseydik grammerimizde bulunan herhangi bir kelime ile eşleşme olduğunda dinleme işlemi bitecekti.
            speechRecognizer.RecognizeAsync(RecognizeMode.Multiple);
            //Arkaplandaki seslere karşı önlemimizi alıyoruz.
            sensor.AudioSource.EchoCancellationMode = EchoCancellationMode.None;
            sensor.AudioSource.AutomaticGainControlEnabled = false;
        }

Bu işlemin ardından kullanacağımız kelimeleri tanımlayalım.

 private SpeechRecognitionEngine Tanimlama()
        {
            //Tanımlayıcıyı kuralım
            RecognizerInfo ri = GetKinectRecognizer();
            //Dinlemeyi yapacak değişkenimizi tanımlayalım
            SpeechRecognitionEngine kulak;
            kulak = new SpeechRecognitionEngine(ri.Id);

            //Kullanacağımız kelimeleri tanımlayalım
            var grammar = new Choices();
            grammar.Add("red");
            grammar.Add("yellow");
            grammar.Add("merhaba");
            grammar.Add("nevarneyok");
            grammar.Add("iyidir");
            //Tanımladığımız kelimeleri grammar haline getirelim
            var gb = new GrammarBuilder { Culture = ri.Culture };
            gb.Append(grammar);

            //Gramerimizi yükleyelim
            var g = new Grammar(gb);
            kulak.LoadGrammar(g);            
            
            kulak.SpeechRecognized += SreSpeechRecognized;
            kulak.SpeechHypothesized += SreSpeechHypothesized;
            kulak.SpeechRecognitionRejected += SreSpeechRecognitionRejected;
            return kulak;
        }

Gelen ses verilerini karşılaştırıp bizlere yardımcı olan eventlarımızı tanımlayalım.

 

 private void RejectSpeech(RecognitionResult result)
        {
            txtblck2.Text = "Affedersiniz anlayamadım ?";
            ellipse1.Fill = Brushes.White;            
        }
        private void SreSpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
        {
            RejectSpeech(e.Result);
        }
        private void SreSpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        {
            //e.Result.Text==> Grammerimizdeki benzetilen ses
            //e.Result.Confidence==> Bu benzetmeninin güvenilirlik oranı yani benzetme oranı da diyebiliriz
            txtblck1.Text = "Benzetilen: " + e.Result.Text + " " + e.Result.Confidence; 
        }
        private void SreSpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            //Bu kısım çok önemli. Burada güvenilirlik 0.8'ten az ise geçersiz sözcük olarak işlem yapılıyor.
            //Güvenilirlik oranını için 0.4 ile 0.8 arası idealdir. Daha düşük seçerseniz hatalı işlem yaparsınız. 
            //Daha yüksek seçersenizde kullanıcıyı fazla zorlamış olursunuz.
            if (e.Result.Confidence < 0.8)
            {
                this.RejectSpeech(e.Result);
                return;
            }           
            switch (e.Result.Text.ToUpperInvariant())
            {
                case "RED":
                    txtblck1.Text += " Soylenen:" + e.Result.Text;
                    ellipse1.Fill = Brushes.Red;
                    txtblck2.Text = "";
                    break;
                case "YELLOW":
                    txtblck1.Text += " Soylenen:" + e.Result.Text;
                    ellipse1.Fill = Brushes.Yellow;
                    txtblck2.Text = "";
                    break;
                case "MERHABA":
                    Yazdir('B',"Merhaba");
                    Yazdir('K',"Merhaba Sahip");  
                    break;
                case "NEVARNEYOK":
                    Yazdir('B', "Ne var ne yok?");
                    Yazdir('K', "İyidir sahip, sende ne var ne yok?");
                    break;
                case "IYIDIR":
                    Yazdir('B', "İyidir");                    
                    break;
                default:
                    break;
            }
        }

Son olarak diyaloğumuzu ekrana yazdıran kodlarımız…

private void Yazdir(char kim, string soz)
        {
            Paragraph para = new Paragraph();
            switch(kim)
            {
                case 'B':                    
                    para.Inlines.Add("B: " + soz);
                    mcFlowDoc.Blocks.Add(para);
                    richTextBox1.Document = mcFlowDoc;
                    break;
                case 'K':
                    para.Inlines.Add(new Bold(new Run("K: " + soz)));
                    mcFlowDoc.Blocks.Add(para);
                    richTextBox1.Document = mcFlowDoc;
                    break;
            }            
        }

Gelin programımızın ekran çıktılarına bakalım.

Tanınamayan bir kelime söylendiğinde

“Red” denildiğinde

“Yellow” denildiğinde

“Merhaba” denildiğinde

“Ne var ne yok” denildiğinde

“İyidir” denildiğinde

Gördüğünüz gibi Kinect’i konuşarak yönetebiliyoruz. Farklı senaryolarda farklı şekillerde yönetebilirsiniz. Yapmış olduğum programın kodlarını buradan indirebilirsiniz. Bir sonraki makalemde görüşmek dileğiyle…