Rozpoznawanie mowy po raz kolejny

0

Witam
Wiem ze temat już wiele razy był wałkowany "Rozpoznawanie mowy" w delphi.
Testowałem kilka polskich programów do analizy z mniejszym lub większym powodzeniem, niestety nie spełniły moich oczekiwań, wiec odpuściłem język polski i padło na sapi 5.1. Mam zainstalowane komponenty o których była mowa, na forum.

Rozpoznawanie mowy

Jednak nie wiem jak się do tego zabrać. Ktoś kiedyś pisał ze wystarczy kilka kontrolek. Czy mogę prosić przykładowy fragment kodu, link. Docelowo chodzi mi o to by program działał mniej więcej tak, jednak być bardziej rozbudowany jeśli chodzi o peryferia.

http://www.elektroda.pl/rtvforum/topic1229137.html

A może komuś udało się dokonać sprawnej analizy w języku polskim, jeśli tak to przy pomocy jakiego programu.
Z góry dziękuje za pomoc.

0

Nie mówcie proszę ze nikt nie bawił się w analizę mowy w Sapi...

0

Ja się nie bawiłem, bo bym Ci na pewno odpisał. Ale skoro gościu tak lakonicznie pisze FAQ to albo to jakiś delikatnie pisząc buc albo całośc po pobraniu musi być jakoś udokumentowana albo własności są czytelne w tych 19 komponentach jakie zyskujesz. Tak jak na przykład obsługa plików INI z klasą TIniFile jest banalna, ale i do tego stworzono opisy oraz przykłady żeby było jeszcze banalniejsze.

0

daawno daawno temu, bawilem sie jakimis microsoftowymi kontrolkami do rozpoznawania angielskiego. moze to wlasnie o tym mowisz, nie wiem.
pamietam, ze tam sie podawalo liste potencjalnych poleceń, które ktoś może wypowiedzieć. idealne, do niektórych zastosowań.
pamiętam też, że jeśli zapisało się jakieś polskie słowo fonetycznie, to program to całkiem poprawnie rozpoznawal :)

0

O to to. Masz może jakiś kod przykładowy, żebym choć wiedział jak do tego podejść. Trochę informacji znalazłem na podanym przeze mnie linku do elektrody, ale to niewiele.

0

ja nie wiem... w pierwszym linku ktory podales, w komentarzach masz link od autora i z tego co widze tam jest wszystko czego potrzeba.

0

Tak trochę jest ale Autor dużo uwagi na stronie poświecił elektronice i awaratowi, natomiast o samym mechanizmie rozpoznawania jest niewiele. Ale znalazłem jeszcze to http://edn.embarcadero.com/article/29583. Na początek powinno starczyć.

0

czytaj ze zrozumieniem...

cimak napisał(a)

w pierwszym linku ktory podales

PIERWSZYM, nie drugim. pierwszy to: Rozpoznawanie mowy
no, chyba że z rozpędu indeksujesz od 0 :D

0

No i działa :) . Analiza głosu odbywa się poprzez komponent SpSharedRecoContext gdzie samej analizy dokonujemy poprzez SpSharedRecoContextRecognition, jednak najlepiej dodać więcej kontrolek (możemy obserwować cały proces analizy komend, nasłuch, analizę, porównywanie). Cala procedura jest dość skomplikowana ponieważ program pobiera sobie zadeklarowane wzorce z pliku xml. Jednak się da, nie bawiłem się co prawda z analiza polskich slow ale myślę ze kwestia właściwej deklaracji pod kontem fonetyki. Jeśli ktoś chciałby pobawić się z analiza komend przez SAPI to proponuje pobranie plików z
http://www.blong.com/Conferences/DCon2002/Speech/SAPI51/SAPI51.htm
i analizę kodu "CommandAndControl". Skuteczność jest zadowalająca zwłaszcza gdy połączyć analizę z syntezatorem mowy. (komponent spVoice) :)

0

Synteza mowy I: Fonemizacja: http://informatyka.wroc.pl/node/332
Synteza mowy II: Akcent i zabawa dźwiękiem: http://informatyka.wroc.pl/node/445
Synteza mowy III: Finał: http://informatyka.wroc.pl/node/546

0

Działa to dość sprawnie, w chwili obecnej chciałbym dodać procedurę "słowa kluczowego" czyli słowa do po którym program czekał by na następna komendę, a do wypowiedzenia którego ignorował by inne komendy. Ponieważ kilka razy zdarzyło się ze program sam niewłaściwie interpretował jakieś dźwięki z otoczenia.

W chwili obecnej za "dopasowanie" komend z xml. odpowiada jedno ze zdarzeń komponentu z palety Sapi.

 
procedure TSAPI.SpSharedRecoContextRecognition(ASender: TObject;
  StreamNumber: Integer; StreamPosition: OleVariant;
  RecognitionType: TOleEnum; const Result: ISpeechRecoResult);
begin
with Result.PhraseInfo do
  begin
    Log('Wykonuje Polecenie: %s', [GetText(0, -1, True)]);
    case GetPropValue(Result, ['sapi']) of
      1: zdarzenie1;
      2: zdarzenie2;
      3: zdarzenie3;
      4: zdarzenie4;
      5: zdarzenie5;
      6: zdarzenie6;
      7: zdarzenie7;
      8: zdarzenie8;
    end
  end;
end;

A plik xml. wygląda tak

<GRAMMAR LANGID="809">
  
<!--COMMANDSSapi-->

<DEFINE>
    <ID NAME= "RID_start" VAL="1"/>
  </DEFINE>
<!-- Rule definitions -->

   <RULE NAME="sapiform"  TOPLEVEL="ACTIVE">
<O>please</O>
      <L PROPNAME="sapi">
      <P VAL="1">zwrot1</P>
      <P VAL="2">zwrot2</P>
      <P VAL="3">zwrot3</P>
      <P VAL="4">zwrot4</P>
      <P VAL="5">zwrot5</P>
      <P VAL="6">zwrot6</P>
      <P VAL="7">zwrot7</P>
      <P VAL="8">zwrot8</P>
    </L>
 </RULE>
</GRAMMAR>

Siedzę już przy tym kilka dni i nic sensownego mi nie wyszło jakieś pomysły.

0

a mógł byś wstawić na neta twój projekt? chętnie bym go przeglądną...

0

Niestety na ta chwile nie zamierzam jeszcze udostępniać kodu w necie (program posiada mnóstwo błędów i braków). Dodam tylko ze idąc śladem Autora "stephane" (link do elektrody w pierwszym poście) program potrafi obsługiwać 8 urządzeń zewnętrznych poprzez kartę przekaźników, oraz zbierać dane z 11 czujników zewnętrznych (NO/NC, temperatury, oraz czujniki zmiany napięcia). Główny interface użytkownika staram się oprzeć na SAPI. Jednak pojawiła się konieczność interpretacji "słowa kluczowego". Program sam kilkukrotnie blednie interpretował otoczenie i np. zasłaniał rolety :/.

Czy ktoś ma możne pomysł jak to zrobić.

0
tayamoto napisał(a)

Działa to dość sprawnie, w chwili obecnej chciałbym dodać procedurę "słowa kluczowego" czyli słowa do po którym program czekał by na następna komendę, a do wypowiedzenia którego ignorował by inne komendy. Ponieważ kilka razy zdarzyło się ze program sam niewłaściwie interpretował jakieś dźwięki z otoczenia.

W chwili obecnej za "dopasowanie" komend z xml. odpowiada jedno ze zdarzeń komponentu z palety Sapi.

 
procedure TSAPI.SpSharedRecoContextRecognition(ASender: TObject;
  StreamNumber: Integer; StreamPosition: OleVariant;
  RecognitionType: TOleEnum; const Result: ISpeechRecoResult);
begin
with Result.PhraseInfo do
  begin
    Log('Wykonuje Polecenie: %s', [GetText(0, -1, True)]);
    case GetPropValue(Result, ['sapi']) of
      1: zdarzenie1;
      2: zdarzenie2;
      3: zdarzenie3;
      4: zdarzenie4;
      5: zdarzenie5;
      6: zdarzenie6;
      7: zdarzenie7;
      8: zdarzenie8;
    end
  end;
end;

A plik xml. wygląda tak

<GRAMMAR LANGID="809">
  
<!--COMMANDSSapi-->

<DEFINE>
    <ID NAME= "RID_start" VAL="1"/>
  </DEFINE>
<!-- Rule definitions -->

   <RULE NAME="sapiform"  TOPLEVEL="ACTIVE">
<O>please</O>
      <L PROPNAME="sapi">
      <P VAL="1">zwrot1</P>
      <P VAL="2">zwrot2</P>
      <P VAL="3">zwrot3</P>
      <P VAL="4">zwrot4</P>
      <P VAL="5">zwrot5</P>
      <P VAL="6">zwrot6</P>
      <P VAL="7">zwrot7</P>
      <P VAL="8">zwrot8</P>
    </L>
 </RULE>
</GRAMMAR>

Siedzę już przy tym kilka dni i nic sensownego mi nie wyszło jakieś pomysły.

Rozumiem ze nikt nie ma żadnych pomysłów jak dodać słowo kluczowe.

0

nie rozumiem masz komendy które mówisz i on to rozum mi coś tam tworzy. więc tak samo tworzysz słowa kluczowe nie?

0

Nie do końca. Załóżmy ze program ma zadeklarowanych kilkadziesiąt komend rożnej maści, wówczas kłopotliwe staje się np. oglądanie filmów bądź słuchanie muzyki ponieważ silnik nasłuchu cały czas dokonuje analizy dźwięków otoczenia z masa wzorców. Słowo kluczowe ma stanowić swoistego rodzaju furtkę czyli słowo po dopasowaniu którego, program zaczyna nasłuchiwać pozostałych komend. Tak w dużym uproszczeniu :).

0

no to sam sobie odpowiedziałeś program cały czas nasłuchuje (obciążenie to jest spowodowane nie optymalnym kodem, angażowaniu wielu nie potrzebnych operacji) i działa na komendy, jak będzie czekał na słowo kluczowe to też analizuje środowisko czyż nie ? taką pętle chcesz zrobić dodatkowo ?
Jak chcesz to ci mogę dać z takiego czegoś I-Droid01 tego było taka prenumerata i ja mam kod źródłowy os tego robotka ;] on tam ma komendy głosowe itp mogło by ci to coś pomóc tylko że to w C jest pisane a podejrzewam nie znasz tego i nawet nie przetłumaczysz tym bardziej ...
co do tego os to procek był coś mniej niż 500mhz i chyba 32 mb ramu


Ja bym to zrobił tak że masz rozpoznawanie poszczególnych literek i przypasowywanie ich do wyrazów (komend z odpowiednimi procedurami)

0

Nie zapominajmy ze całość opiera się na Sapi i zasobach samego Windowsa, forma tylko przechwytuje kilka niezbędnych operacji. Sam program działa stabilnie nawet po kilkugodzinnej pracy.
(będę wdzięczny za każda pomoc nawet w C)

1

Mówisz masz
http://proqixproj.comze.com/downloads/linux-2.4.26-idroid.tar.bz2
~ 30,8 MB
~ 200 KB/s
To na linuxie jest oparte ;] jak chcesz analizować to zacznij od pliku main w init któryś z plików to będzie

o dokumentacji zapomniałem
http://proqixproj.comze.com/downloads/i-d01_doc.rar

0

skoro masz juz opanowene rozpoznawanie polecen, to dodaj sobie jedno polecenie - slowo klucz, ktore "otworzy tę furtkę". a furtką może byc nawet zmienna typu boolean. poza tym, z tego co pamietam, to xml moze byc ladowany dynamicznie do programu. laduj xml z "poleceniami" dopiero w momencie gdy wylapiesz slowo-klucz (zawarte w innym xmlu).

0

Nie chce deklarować dodatkowego pliku xml. bo jeśli pojawi sie konieczność utworzenia dodatkowych podkategorii komend to utonę w plikach xml. Próbowałem zrobić to jako kilka gałęzi xml na zasadzie zmiennej globalnej. gdzie do form create ładowana by była tylko kategoria xml z jedna komenda jako zdarzenie gałęzi miało następować dynamiczne ładowanie kolejnej gałęzi z xml. Jednak podczas uruchamiania programu całość staje na:

 
SRGrammar.CmdLoadFromFile('Grammar.xml',SLODynamic);

Nie wiem czy ten mechanizm to doby trop.

0
  1. Jaki błąd to jest (z debuggera)
  2. Podaj całą procedurę bo nie wiadomo co dałeś przed ...
0

Chodzi o form create. Ładowanie xml do pamięci błąd wywala debuger.

 
procedure TSAPI.FormCreate(Sender: TObject);
begin
  SpSharedRecoContext.EventInterests := SREAllEvents;
  SRGrammar := SpSharedRecoContext.CreateGrammar(0);
  SRGrammar.CmdLoadFromFile('Grammar.xml',SLODynamic);
  SRGrammar.CmdSetRuleIdState(0, SGDSActive);
end;
0

Ładowanie xml do pamięci błąd wywala debuger.

No raczej że debugger, bo to oczywiste. Koledze proqix chodziło o komunikat błędu. Więc może najpierw naucz się szukać błędów z jakiegoś tutka, potem nam powiedz co to za błąd, gdzie on występuje i takie tam.

0

Błąd pojawił się gdy zmodyfikowałem xml. powrót do wcześniejszej wersji rozwiązał problem. W chwili obecnej chce dynamicznie ładować sekcje z xml miedzy znacznikami <RULE NAME="" i </RULE>. W chwili obecnej przeszukałem już chyba wszystko co było w Google i dotyczyło analizy mówi w sapi. Na pewno kwestia nie jest trudna dla wyjadaczy jednak ja bawię w delphi od 3 miesięcy. Jeśli ktoś ma "konstruktywne" pomysły jak użyć procedury form create tak by dynamicznie ładowała jedna z np. 5 sekcji z xml. będę wdzięczny.

0

Ok. wystarczyła właściwa deklaracja sekcji w xml. w chwili obecnej interpretacja komend głosowych odbywa się na 3-stopniowym menu.
Bardzo uproszczona nawigacje (drzewo jest bardziej rozbudowane) przedstawia poniższy schemat, oczywiście każda z gałęzi posiada również możliwość zamknięcia drzewa, jak i podczas załadowania 2 poziomu uruchamiany jest zegar który w przypadku nie zadeklarowania żadnej z komend 2 stopnia na nowo ładuje 1 poziom (słowo kluczowe). Całość połączona jest miedzy innymi z syntezatorem informującym o przejściu na poszczególne poziomy.

                                                       ----------- play----------
                                                    /                                        \ 
                                np.odtwarzacz  ----------inne opcje-----------
                              /                     \                                         /    \

słowo kluczowe--1poziom komenda do niższego poziomu
\ poziom 2 -słowo zamykające powrót do poziomu nasłuchu "słowa kluczowego"
program-----program sprzętowy n-------- /
\ \ /
-------program sprzętowy n------------
\ /
komenda do niższego poziomu

Temat do zamknięcia dziękuje za rady i zainteresowanie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1