Kürzlich bin ich zu Ameft (NFL) gekommen. Ich kann jedoch kein Englisch verstehen. .. .. Selbst wenn Sie die Stimme nicht verstehen, können Sie sie irgendwie entziffern, indem Sie sie schreiben? Als ich nachdachte, forderte ich mich heraus, einen Sprachtext von Spielerinterviews mit Raspberry Pi 3 × Julius × Watson (Speech to Text) zu erstellen.
Das Bild sieht so aus Getting robots to listen: Using Watson’s Speech to Text service
Es wird davon ausgegangen, dass Folgendes bereit ist. Listen Sie als Referenz den Link der Site auf, auf die ich verwiesen habe
Julius scheint eine Lesedatei und eine Grammatikdatei zu haben, um die Authentifizierung zu beschleunigen. Nachdem ich beide ausprobiert hatte, entschied ich mich, diesmal die Grammatikdatei zu verwenden.
Die Überprüfungsergebnisse finden Sie unter Raspberry Pi 3 x Julius (Lese- und Grammatikdatei).
Wenn Julius im Modulmodus gestartet wird (*), wird das Audio in XML zurückgegeben. Wenn Sie "Watson starten" sagen, erhalten Sie das folgende XML.
<RECOGOUT>
<SHYPO RANK="1" SCORE="-2903.453613" GRAM="0">
<WHYPO WORD="Watson" CLASSID="Watson" PHONE="silB w a t o s o N silE" CM="0.791"/>
</SHYPO>
</RECOGOUT>
<RECOGOUT>
<SHYPO RANK="1" SCORE="-8478.763672" GRAM="0">
<WHYPO WORD="Watson fing an" CLASSID="Watson fing an" PHONE="silB w a t o s o N k a i sh i silE" CM="1.000"/>
</SHYPO>
</RECOGOUT>
Analysieren Sie daher für das gesprochene Wort das XML und beschreiben Sie den auszuführenden Prozess. (Es ist nicht gut, aber es ist solide ...)
#Stimme beurteilen und verarbeiten
def decision_word(xml_list):
watson = False
for key, value in xml_list.items():
if u"Razz Pie" == key:
print u"Ja. Was ist es?"
if u"Watson" == key:
print u"Verstanden. bereiten."
watson = True
return watson
Geändert, um den Julius-Server im Unterprozess zu starten
#Starten Sie den Julius Server
def invoke_julius():
logging.debug("invoke_julius")
# -Verbieten Sie die Protokollausgabe mit der Option nolog
reccmd = ["/usr/local/bin/julius", "-C", "./julius-kits/grammar-kit-v4.1/hmm_mono.jconf", "-input", "mic", "-gram", "julius_watson","-nolog"]
p = subprocess.Popen(reccmd, stdin=None, stdout=None, stderr=None)
time.sleep(3.0)
return p
#Julius Server
JULIUS_HOST = "localhost"
JULIUS_PORT = 10500
#Verbinde dich mit Julius
def create_socket():
logging.debug("create_socket")
# TCP/Verbinde dich mit Julius mit IP
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((JULIUS_HOST, JULIUS_PORT))
sock_file = sock.makefile()
return sock
Wie oben erwähnt, wird XML von Julius zurückgegeben. Holen Sie sich also die Tags -Tag vorhanden ist, tritt beim XML-Parsing ein Fehler auf, sodass eine andere Verarbeitung als </ s> enthalten ist.
#Extrahieren Sie das angegebene Tag aus den Daten von Julius
def extract_xml(tag_name, xml_in, xml_buff, line):
xml = False
final = False
if line.startswith("<RECOGOUT>"):
xml = True
xml_buff = line
elif line.startswith("</RECOGOUT>"):
xml_buff += line
final = True
else:
if xml_in:
xml_buff += escape(line)
xml = True
return xml,xml_buff,final
# <s>Tags entfernt (entsprechend, weil beim XML-Parsing ein Fehler aufgetreten ist)
def escape(line):
str = line.replace("<s>",'')
str = str.replace('</s>','')
return str
#Analysieren Sie das XML der Julius-Analyseergebnisse
def parse_recogout(xml_data):
#Holen Sie sich das Wort des Erkennungsergebnisses
#Ergebnisse im Wörterbuch speichern
word_list = []
score_list = []
xml_list = {}
for i in xml_data.findall(".//WHYPO"):
word = i.get("WORD")
score = i.get("CM")
if ("[s]" in word) == False:
word_list.append(word)
score_list.append(score)
xml_list = dict(izip(word_list, score_list))
return xml_list
Es ist ein bisschen lang, aber das Ganze von 1.1 bis 1.3 sieht so aus.
#Extrahieren Sie das angegebene Tag aus den Daten von Julius
def extract_xml(tag_name, xml_in, xml_buff, line):
xml = False
final = False
if line.startswith("<RECOGOUT>"):
xml = True
xml_buff = line
elif line.startswith("</RECOGOUT>"):
xml_buff += line
final = True
else:
if xml_in:
xml_buff += escape(line)
xml = True
return xml,xml_buff,final
# <s>Tags entfernt (entsprechend, weil beim XML-Parsing ein Fehler aufgetreten ist)
def escape(line):
str = line.replace("<s>",'')
str = str.replace('</s>','')
return str
#Analysieren Sie das XML der Julius-Analyseergebnisse
def parse_recogout(xml_data):
#Holen Sie sich das Wort des Erkennungsergebnisses
#Ergebnisse im Wörterbuch speichern
word_list = []
score_list = []
xml_list = {}
for i in xml_data.findall(".//WHYPO"):
word = i.get("WORD")
score = i.get("CM")
if ("[s]" in word) == False:
word_list.append(word)
score_list.append(score)
xml_list = dict(izip(word_list, score_list))
return xml_list
#Stimme beurteilen und verarbeiten
def decision_word(xml_list):
watson = False
for key, value in xml_list.items():
if u"Razz Pie" == key:
print u"Ja. Was ist es?"
if u"Watson" == key:
print u"Verstanden. bereiten."
watson = True
return watson
#Julius Server
JULIUS_HOST = "localhost"
JULIUS_PORT = 10500
#Starten Sie den Julius Server
def invoke_julius():
logging.debug("invoke_julius")
# -Verbieten Sie die Protokollierung mit der Option nolog
#Demnächst,-Geben Sie das Protokoll in eine Datei mit der Option logfile usw. aus.
reccmd = ["/usr/local/bin/julius", "-C", "./julius-kits/grammar-kit-v4.1/hmm_mono.jconf", "-input", "mic", "-gram", "julius_watson","-nolog"]
p = subprocess.Popen(reccmd, stdin=None, stdout=None, stderr=None)
time.sleep(3.0)
return p
#Julius Server trennen
def kill_process(julius):
logging.debug("kill_process")
julius.kill()
time.sleep(3.0)
#Verbinde dich mit Julius
def create_socket():
logging.debug("create_socket")
# TCP/Verbinde dich mit Julius mit IP
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((JULIUS_HOST, JULIUS_PORT))
sock_file = sock.makefile()
return sock
#Enge Verbindung mit Julius
def close_socket(sock):
logging.debug("close_socket")
sock.close()
#Hauptverarbeitung
def main():
#Starten Sie den Julius Server
julius = invoke_julius()
#Verbinde dich mit Julius
sock = create_socket()
julius_listening = True
bufsize = 4096
xml_buff = ""
xml_in = False
xml_final = False
watson = False
while julius_listening:
#Holen Sie sich Analyseergebnisse von Julius
data = cStringIO.StringIO(sock.recv(bufsize))
#Holen Sie sich eine Zeile aus dem Analyseergebnis
line = data.readline()
while line:
#Nur die Zeile mit dem Analyseergebnis der Stimme wird extrahiert und verarbeitet.
#Extrahieren und verarbeiten Sie nur das RECOGOUT-Tag.
xml_in, xml_buff, xml_final = extract_xml('RECOGOUT', xml_in, xml_buff, line)
if xml_final:
#Mxl analysieren
logging.debug(xml_buff)
xml_data = fromstring(xml_buff)
watson = decision_word( parse_recogout(xml_data))
xml_final = False
#Wenn das Ergebnis "Watson" ist, wechseln Sie zur Sprachauthentifizierung
if watson:
julius_listening = False #Julius war fertig
break
#Holen Sie sich eine Zeile aus dem Analyseergebnis
line = data.readline()
#Steckdose schließen
close_socket(sock)
#Julius trennen
kill_process(julius)← Watsons Sprachauthentifizierung "Speech to Text" zeichnet mit Arecord auf, sodass Julius die Verbindung trennt (weil das Mikrofongerät kollidiert, ...)
if watson:
speechToText()← Wenn Ihnen "Watson" mitgeteilt wird, führen Sie die Prozesse ③ und ④ aus
def initial_setting():
#Protokolleinstellungen
logging.basicConfig(filename='websocket_julius2.log', filemode='w', level=logging.DEBUG)
logging.debug("initial_setting")
if __name__ == "__main__":
try:
#Initialisierungsprozess
initial_setting()
#Hauptverarbeitung
main()
except Exception as e:
print "error occurred", e, traceback.format_exc()
finally:
print "websocket_julius2...end"
Starten Sie den Sprachaufzeichnungsprozess (führen Sie den Befehl arecord aus) im Multithread. Senden Sie bei jeder Aufnahme Binärdaten an Watson, damit Sie das Audio in Echtzeit in Text umwandeln können. (* .Datenaustausch mit Watson wird später beschrieben)
def opened(self):
self.stream_audio_thread = threading.Thread(target=self.stream_audio)
self.stream_audio_thread.start()
#Starten Sie den Aufnahmevorgang
def stream_audio(self):
# -Nachricht mit q-Option ausblenden
reccmd = ["arecord", "-f", "S16_LE", "-r", "16000", "-t", "raw", "-q"]
p = subprocess.Popen(reccmd,stdout=subprocess.PIPE)
print 'Bereit. Bitte Stimme'
while self.listening:
data = p.stdout.read(1024)
try:
self.send(bytearray(data), binary=True)← Binärdaten an Watson übergeben
except ssl.SSLError: pass
Verwenden Sie die webSocket-Version von Speech to Text, um Audio in Echtzeit in Text umzuwandeln. Informationen zum Sprechen in Text finden Sie auch unter Ich habe die Watson-Sprachauthentifizierung (Sprechen in Text) ausprobiert.
Implementiert mit Bezug auf diese Beispielquelle Getting robots to listen: Using Watson’s Speech to Text service
Stellen Sie über die Bibliothek für Watson (Watson-Developer-Cloud-0.23.0) eine Verbindung zu Watson her.
class SpeechToTextClient(WebSocketClient):
def __init__(self):
ws_url = "wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize"
username = "XXXXXXX"
password = "XXXXXXX"
auth_string = "%s:%s" % (username, password)
base64string = base64.encodestring(auth_string).replace("\n", "")
self.listening = False
try:
WebSocketClient.__init__(self, ws_url,headers=[("Authorization", "Basic %s" % base64string)])
self.connect()
except: print "Failed to open WebSocket."
# websocket(Verbindung)
def opened(self):
self.send('{"action":"start","content-type": "audio/l16;rate=16000","continuous":true,"inactivity_timeout":10,"interim_results":true}')
Das Ausführungsergebnis (Sprachdaten) des in dem oben beschriebenen Multithread ausgeführten Arecord-Befehls wird an Watson gesendet. Es ist ein bisschen lang, aber ... 2. Sprachaufnahme-3. Wenn ich die Verbindung von Raspberry Pi 3 zu Watson (Speech to Text) zusammenstelle, sieht es so aus.
class SpeechToTextClient(WebSocketClient):
def __init__(self):
ws_url = "wss://stream.watsonplatform.net/speech-to-text/api/v1/recognize"
username = "XXXXXXX"
password = "XXXXXXX"
auth_string = "%s:%s" % (username, password)
base64string = base64.encodestring(auth_string).replace("\n", "")
self.listening = False
try:
WebSocketClient.__init__(self, ws_url,headers=[("Authorization", "Basic %s" % base64string)])
self.connect()
except: print "Failed to open WebSocket."
# websocket(Verbindung)
def opened(self):
self.send('{"action":"start","content-type": "audio/l16;rate=16000","continuous":true,"inactivity_timeout":10,"interim_results":true}')
self.stream_audio_thread = threading.Thread(target=self.stream_audio)
self.stream_audio_thread.start()
#Starten Sie den Aufnahmevorgang
def stream_audio(self):
while not self.listening:
time.sleep(0.1)
# -Nachricht mit q-Option ausblenden
reccmd = ["arecord", "-f", "S16_LE", "-r", "16000", "-t", "raw", "-q"]
p = subprocess.Popen(reccmd,stdout=subprocess.PIPE)
print 'Bereit. Bitte Stimme'
while self.listening:
data = p.stdout.read(1024)
try:
self.send(bytearray(data), binary=True)
except ssl.SSLError: pass
Bei der Verbindung mit webSocket scheint das Analyseergebnis von Watson im Ereignis receive_message empfangen zu werden.
# websockt(Erhalte Nachricht)
def received_message(self, message):
print message
Das Analyseergebnis scheint als JSON-Objekt zurückgegeben zu werden.
Auf diese Weise konnte ich die Stimme in Echtzeit in Text umwandeln.
2017/4/16 Nachtrag Ich habe so ein Video gemacht. https://youtu.be/IvWaHISF6nY
Eindruck, dass die Stimme nicht gut authentifiziert werden kann, wenn mit mehreren Personen gesprochen wird oder wenn Musik vorhanden ist. Trotzdem fand ich es einfach erstaunlich, dass die Stimme in Echtzeit zu Text wurde. Ich möchte immer mehr mit Sprachauthentifizierung spielen.
Recommended Posts