Sprachsteuerung [Überarbeitet]

    • VB.NET

    Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von TrojanosLP.

      Sprachsteuerung [Überarbeitet]

      Hallo Community,
      dies ist mein erstes Tutorial, es geht um Sprachsteuerung in VB.NET.

      1. Allgemeines

      Was wollen wir machen?
      Wir möchten eine Sprachsteuerung programmieren, welche von uns gesprochene Wörter oder Sätze erkennt und darauf reagiert.

      Ihr braucht für die Sprachsteuerung .NET 3.0 oder höher. Ich weiß nicht ob die Sprachsteuerung auf XP läuft. Getestet habe ich sie gerade auf Windows 7 Prof. 64 Bit und XP Home Edition 32 Bit auf Windows 7 funktionierte sie sehr zuverlässig und flüssig. Auf Windows XP wurde ich jedoch mit Fehlermeldungen zugeschüttet welche ich nicht richtig nachvollziehen konnte. Genug geredet jetzt zur richtigen Theorie :D.


      2. Theroie

      Wie funktioniert eine Sprachsteuerung eigentlich? Soweit ich weiß, zeichnet eine Sprachsteuerung den gesprochenen Befehl auf und vergleicht ihn mit einer anderen Stimme. Genauer: Vorher spricht jemand einen Satz, welcher in Buchstaben aufgegliedert wird. Z.B. Ich habe einen tollen Affen. > I | c | h | h | a | b | e usw. Und in diesem Satz müssen alle Buchstaben des Alphabetes vorhanden sein. Danach wird aus den Puzzelteilen das Wort wieder zusammen gelegt und verglichen mit der Aufnahme.
      Ich weiß ist nicht so gut erklärt, wenn es jemand besser formulieren kann bitte mir sagen ich werde es editieren.


      3. Praxis

      Endlich bei der Praxis angekommen und das gelaber ist weg.

      1. Ein Projekt erstellen


      Als erstes brauchen wir ein neues Projekt, eine Konsolenanwendung. (Wahlweise auch eine Windows Forms Anwedung siehe weiter unten.)
      Wenn ihr die Konsolenanwendung erstellt habt fügt einen Verweis hinzu, dafür klickt ihr in Visual Studio auf Projekt > 'Name eures Projektes' - Eigenschaften > Verweise > Hinzufügen > .NET und sucht System.Speech > OK > Fertig wieder zurrück zum Code.

      2. Der Code
      Als erstes Importiert ihr jetzt diese 6 Zeilen:

      VB.NET-Quellcode

      1. Imports System
      2. Imports System.IO
      3. Imports System.Speech
      4. Imports System.Speech.Recognition
      5. Imports System.Speech.Synthesis
      6. Imports System.Threading

      Über Sub Main kommt das:

      VB.NET-Quellcode

      1. Private _GrammarFile As String = Path.GetFullPath("..\..\grammar.xml")
      2. Dim xDoc As XDocument = XDocument.Load(_GrammarFile)Dim WithEvents recognizer As New SpeechRecognitionEngine()
      3. Dim _Waiter As New AutoResetEvent(False)

      Hier wurden erstmal ein paar Variablen deklariert.
      Nun, schreibt ihr in Sub Main() folgenden Code:

      VB.NET-Quellcode

      1. Sub Main()
      2. recognizer.SetInputToDefaultAudioDevice() 'Hier wird das Audio Gerät gesetzt, in diesem Fall das Standard Mikrofon welches in Windows konfiguriert ist.
      3. Console.WriteLine("Ich kenne die folgenden Wörter:") ' Dürfte klar sein was hier passiert.
      4. Console.WriteLine("Das Wort ""Beenden"" wird das Programm beenden." & Environment.NewLine) ' Siehe oben.
      5. For Each xel In xDoc.Elements()(0).Elements()(0).Elements()(0).Elements() ' In dieser Schleife werden alle Items, also Worte, die in der Grammar Datei (Das kommt weiter unten.) deklariert wurden auf der comand line ausgegeben.
      6. Console.WriteLine(xel.Value) ' Gehört zur Schleife.
      7. Next ' Ende der Schleife.
      8. Dim grammar As New Grammar(_GrammarFile, "thema") ' Hier wird die Grammardatei Sprache 'mit einer Varbiable "verbunden"'...
      9. recognizer.UnloadAllGrammars() ' An dieser Stelle wird der Cache von allen 'alten' 'Grammatiken' gelöscht.
      10. recognizer.LoadGrammar(grammar) ' Hier wird die neue 'Grammatik' geladen. Also die Befehle.
      11. recognizer.RecognizeAsync(RecognizeMode.Multiple) ' Jetzt wird die eigentliche Erkennung gestartet.
      12. Console.WriteLine() ' Leerzeile auf die comand line schreiben, dass es schöner aussieht.
      13. _Waiter.WaitOne() ' Hier wird verhindert, dass das Programm geschlossen wird bevor Beenden gesagt wird.
      14. recognizer.Dispose() ' Hier wird der Speicher gelöscht
      15. Console.WriteLine("Programm wird geschlossen...") ' Dürfte klar sein was hier passiert.
      16. Threading.Thread.Sleep(1000) ' Nach 1 Sek wird das Programm komplett beendet.
      17. End Sub


      Wenn bis hierhin alles funktioniert hat ist es super. Dann sind wir fast durch. Sollte hier alles klar sein weil ich es auskommentiert habe.

      Jetzt brauchen wir noch den Sub an dem die Vergleichung also grob die Erkennung wirklich stattfindet. Der sieht folgendermaßen aus:

      VB.NET-Quellcode

      1. Private Sub recognizer_SpeechRecognized(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs) Handles recognizer.SpeechRecognized
      2. Dim spoken_text = e.Result.Text ' Hier wird das Ergebniss der gesprochenen Befehle in eine Variable übernommen zur einfacheren Verwendung im Verlauf des Codes.
      3. If spoken_text = "Beenden" Then _Waiter.Set() ' Hier wird eben bei dem Befehl Beenden das Signal zum beenden des Programmes an den Main Sub geschickt.
      4. Console.WriteLine(spoken_text & " (" & e.Result.Confidence.ToString() & ")") ' Hier wird der Befehl der erkannt wurde in die Konsole geschrieben und dahinter als kleines Plus noch wie gut der Computer den Befehl erkannt hat. In Prozent.
      5. End Sub


      Dürfte auch klar sein, da auskommentiert.

      3. Die XML grammar Datei
      So, das wars eigentlich auch schon. Jetzt kommt aber noch der Aufbau von grammar.xml diese muss in diesem Fall im Verzeichnis liegen in dem auch das Programm ansässig ist. Sie sieht folgendermaßen aus:

      XML-Quellcode

      1. <grammar xmlns="http://www.w3.org/2001/06/grammar"
      2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.w3.org/2001/06/grammar
      3. http://www.w3.org/TR/speech-grammar/grammar.xsd"xml:lang="de-DE" version="1.0">
      4. <rule id="thema" scope="public"><one-of>
      5. <item>Test</item><item>Dies ist ein Test</item>
      6. <item>Beenden</item>
      7. <item>was</item></one-of>
      8. </rule>
      9. </grammar>

      Alsooo, hier stehen die Befehle drin, auf welche das Programm reagieren soll. Ganz oben werden erst einmal die Schemen für die XML Datei angegeben. Das ist für uns aber gerade unwichtig. Darunter wird eine ID angegeben mit der wir im Programm die Befehle ansprechen können. Nun können wir beliebig viele Befehle angeben, indem wir einfach den Befehl durch ein weiteres Item hinzufügen. Einfach unter den jeweils letzen Befehl (In unserem Beispiel 'was') MEIN NEUER BEFEHL</item> schreiben. Diese können dann nacher im Programm verarbeitet werden. Unten werden einfach die oben gemachten Details wieder geschlossen.
      P.S.: Ich habe noch vergessen das ihr auch Englische Befehle verwenden könnt, aber dann müsst ihr in der grammar Datei bei xml:lang das de-DE durch en-EN oder falls das nicht klappt en-US ersetzen.

      VIEL SPAß damit.


      4. Ein paar Sachen von mir an die Welt


      Ich möchte mich an dieser Stelle bei ErfinderDesRades sehr bedanken, da er für diese Tutorial den Code nochmal umgeschrieben hat, sodass es eigentlich bei niemanden mehr Probleme geben dürfte, außerdem hat er den Code noch deutlich vereinfacht und übersichtlicher gemacht und ein Form Beispiel dazu geschrieben. Also Bedankt euch alle noch geistlich bei ErfinderDesRades.

      Morgen werde ich ein Visual Studio Exampel und ein Forms Beispiel anhängen. Einen schönen Abend wünsche ich noch.

      Quelle: amenthes.de/index.php/2007/12/…t-35-zur-spracherkennung/
      Dateien

      Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „ErfinderDesRades“ () aus folgendem Grund: SampleProjekt angehängt

      Hallo,

      ich habe das ganze in einer Consolen Anwendung bereits zum laufen gebracht und habe es jetzt in eine Forms anwendung umgebaut.

      Ich bekomme jetzt bei

      VB.NET-Quellcode

      1. For Each xel In xDoc.Elements()(0).Elements()(0).Elements()(0).Elements()
      2. Console.WriteLine(xel.Value)
      3. Next


      Folgenden Fehler:

      Die Schnittstelle "System.Collections.Generic.IEnumerable(Of System.Xml.Linq.XElement)" kann nicht indiziert werden, da keine Standardeigenschaft vorhanden ist.

      Hat da jemand eine Idee wie ich das beheben kann?

      Grüße,
      Na ja, so richtig wird das nicht funktionieren, da du die, denk ich, brauchst. Kannst ja mal versuchen, das mit dem Cleverbot zu verbinden. Nur so ne Idee.
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Hab auch nochmal eine Frage: Bei mir wird "Beenden" nicht erkannt, ich glaube das liegt an der Silbentrennung also: Be-en-den ich glaube das Programm möchte lieber ein längeres e höhren, oder?
      MFG VBWorld
      Mathe ist für alle die, die nicht mit dem Taschenrechner umgehen können :D
      Das funktioniert bei mir wunderbar :) Wenn ich jetzt aber möchte dass mein programm etwas sagt oder schreibt wie kann ich das mit einbinden?
      Also wenn ich feste sätze definiere wie "sag ich liebe dich" dann macht er das auch kein Problem.

      Ich will aber viele undefinierte sätze verarbeiten können wie Sag "du bist nett" dann will ich ja "du bist nett" wieder bekommen und nicht "sag du bist nett"

      Edit by ~blaze~:
      Anstößige Formulierung abgewandelt
      Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „~blaze~“ ()

      Hi
      ich habe deinen Code benutzt um eine sehr große Sprachsteuerung zu erstellen. (Ich hoffe das war in Ordnung)
      Hast du eine Idee wie ich es hinbekommen kann, mehrere <item> Elemente hintereinander zu sagen. Dann müsste ich nicht jeden Satz einzeln aufschreiben.
      ich hoffe du kannst mir helfen.
      Mit freundlichen Grüßen,
      TrojanosLP