У меня есть python скрипт, который использует движок Google STT и затем просматривает словарь, чтобы проверить, где находится наибольшее совпадение (отношение), используя difflib SequenceMatcher
UPDATE (лучшее объяснение того, что должен делать скрипт ):
- переменная изговоренно содержит строку (из движка Google STT, фактически микрофон) - скажем, ее значение равно «lights»
- есть вложенный словарь, где каждое горячее слово (например, «светится») на "," закрытые жалюзи "и т. д. c.) содержит команду для соответствующего кодирования. Есть «горячее слово» и есть «команда». В этом примере значение горячего слова, скажем, «включенные огни» и соответствующая команда «выполнить некоторый код для включения лампочек»
- команда будет выполняться только при наличии некоторого процента (по крайней мере, 50% или 0,5 в десятичное) совпадение между переменной изговорено и горячим словом. Таким образом, существует значение для l oop, которое проходит через словарь и использует difflib.SequenceMatcher сравнивает переменную изговорно со всеми горячими словами из словаря, а затем записывает результат (процент) в ключ "razlika_izgovoreno_hotword" для каждого соответствующего горячего слова.
- Теперь у нас есть словарь с этими данными (пример):
hotword:"lights on"
komanda:"execute some code to turn on the lights"
razlika_izgovoreno_hotword:"0.90"
hotword:"blinds shut"
komanda:"execute some code shut blinds"
razlika_izgovoreno_hotword:"0.10"
etc.
На следующем шаге я использую для l oop (это l oop, выделенный в коде, который доставляет мне проблемы), чтобы получить максимальное значение для razlika_izgovoreno_hotword из словаря и соответствующие значения из ключей hotword и komanda. Но, если честно, l oop - это колбаса, и я действительно не понимаю, как она работает (я новичок в python), но мне удалось получить максимальное значение для razlika_izgovoreno_hotword и значение komanda. Я только НЕ МОГУ получить значение горячего слова, которое не обязательно для работы скрипта, но приятно иметь его для отладки. Ожидаемый результат (лучшее соответствие по сравнению с переменной изговорено) в этом примере, конечно, является горячим словом «светится» с коэффициентом совпадения 0,9, а затем выполняется переменная komanda = «выполнить некоторый код для включения света».
ПОЛНЫЙ рабочий код:
#!/usr/bin/env python3.6
# -*- coding: UTF-8 -*-
# NOTE: this example requires PyAudio because it uses the Microphone class
import snowboydecoder
import sys
import signal
import subprocess
import speech_recognition as sr
import urllib
import difflib
interrupted = False
def signal_handler(signal, frame):
global interrupted
interrupted = True
def interrupt_callback():
global interrupted
return interrupted
if len(sys.argv) == 1:
print("Error: need to specify model name")
print("Usage: python demo.py your.model")
sys.exit(-1)
model = sys.argv[1]
# capture SIGINT signal, e.g., Ctrl+C
signal.signal(signal.SIGINT, signal_handler)
detector = snowboydecoder.HotwordDetector(model, sensitivity=0.5)
print('Snowboy listening... Press Ctrl+C to exit')
# main loop
def detektiran():
snowboydecoder.play_audio_file()
r = sr.Recognizer()
with sr.Microphone() as source:
print("Say something!")
audio = r.listen(source,phrase_time_limit=5)
# recognize speech using Google Speech Recognition
try:
# for testing purposes, we're just using the default API key
# to use another API key, use `r.recognize_google(audio, key="GOOGLE_SPEECH_RECOGNITION_API_KEY")`
# instead of `r.recognize_google(audio)`
print("Izgovoreno: " + r.recognize_google(audio, language="hr-HR"))
izgovoreno = r.recognize_google(audio, language="hr-HR")
##############KOMANDE - ubacivanje novih i promjena postojecih#################################################
glasovne_naredbe = {
###svijetlo 1 prostorija
'glasovno1' : {
"hotword": "svijetlo",
"komanda": "urllib.urlopen('http://127.0.0.1:8080/json.htm?type=command¶m=switchlight&idx=2&switchcmd=On')"
},
###zvuk najglasnije
'glasovno2' : {
"hotword": "najglasnije",
"komanda": "subprocess.Popen(['amixer', 'set', 'Master', '100%'])"
},
###zvuk najtiše
'glasovno3' : {
"hotword": "najtiše",
"komanda": "subprocess.Popen(['amixer', 'set', 'Master', '10%'])"
},
###zvuk srednje glasno
'glasovno4' : {
"hotword": "srednje glasno",
"komanda": "subprocess.Popen(['amixer', 'set', 'Master', '50%'])"
},
###zvuk smanji
'glasovno5' : {
"hotword": "smanji",
"komanda": "subprocess.Popen(['amixer', 'set', 'Master', '10%-'])"
},
###zvuk pojačaj
'glasovno6' : {
"hotword": "pojačaj",
"komanda": "subprocess.Popen(['amixer', 'set', 'Master', '10%+'])"
}
}
###############KOMANDE KRAJ##########################################################################
i = 0
for a, b in glasovne_naredbe.items():
#print(a, b)
i += 1
glasovno = ("glasovno" + str(i))
hotword = (glasovne_naredbe[glasovno]['hotword'])
hotword_decoded = hotword.decode('utf-8')
razlika_izgovoreno_hotword = difflib.SequenceMatcher(None, izgovoreno, hotword_decoded).ratio() #svaka razlika iznad 0.50 aktivira komandu
#print ("Omjer(%s) Izgovoreno (%s) Hotword (%s)" % (razlika_izgovoreno_hotword, izgovoreno, hotword_decoded))
#ubacivanje (privremenog) rezultata razlika_izgovoreno_hotword u dictionary
glasovne_naredbe[glasovno]['razlika_izgovoreno_hotword'] = razlika_izgovoreno_hotword
#izvlacenje maksimalnog razlika_izgovoreno_hotword iz dictionarya
razlika_izgovoreno_key, razlika_izgovoreno_value, komanda_value, komanda_key = \
max(((raz_k,raz_v,k_k,k_v) for inner_d in glasovne_naredbe.values() for raz_k,raz_v in inner_d.items() for k_v,k_k in inner_d.items()))
print("Vrijednost razlika_izgovoreno postotak: %s" % (razlika_izgovoreno_value))
print("Komanda: %s" % (komanda_value))
if razlika_izgovoreno_value >= 0.50: #ako je ratio u postotku veci od 0.50, pokreni komandu
exec(komanda_value)
#dong zvuk da je uspjesno izvedeno
else:
print ("Izgovoreno se ne podudara minimalno 50% sa nijednim hotwordom, molim ponovi!")
except sr.UnknownValueError:
print("Google Speech Recognition could not understand audio")
except sr.RequestError as e:
print("Could not request results from Google Speech Recognition service; {0}".format(e))
detector.start(detected_callback=detektiran,
interrupt_check=interrupt_callback,
sleep_time=0.03)
detector.terminate()
У меня проблема с этой частью кода, когда я могу получить значение MAX для "razlika_izgovoreno_value", и я могу получить соответствующее "komanda_value", но я не могу получить соответствующее значение "hotword_value".
razlika_izgovoreno_key, razlika_izgovoreno_value, komanda_value, komanda_key, hotword_key, hotword_value = \
max(((raz_k,raz_v,k_k,k_v,h_v,h_k) for inner_d in glasovne_naredbe.values() for raz_k,raz_v in inner_d.items() for k_v,k_k in inner_d.items() for h_v,h_k in inner_d.items()))
Есть совет? Я пробовал каждую комбинацию для l oop, но я просто не могу получить значение горячего слова.
EDIT: Вывод glasovne_naredbe (тестовое слово для сравнения - "test")
Izgovoreno: test
{'glasovno1':
{'komanda': "urllib.urlopen('http://127.0.0.1:8080/json.htm? type=command¶m=switchlight&idx=2&switchcmd=On')",
'hotword': 'svijetlo',
'razlika_izgovoreno_hotword': 0.16666666666666666},
'glasovno2':
{'komanda': "subprocess.Popen(['amixer', 'set', 'Master', '100%'])",
'hotword': 'najglasnije',
'razlika_izgovoreno_hotword': 0.13333333333333333},
'glasovno3':
{'komanda': "subprocess.Popen(['amixer', 'set', 'Master', '10%'])",
'hotword': 'najti\xc5\xa1e',
'razlika_izgovoreno_hotword': 0.36363636363636365},
'glasovno4':
{'komanda': "subprocess.Popen(['amixer', 'set', 'Master', '50%'])",
'hotword': 'srednje glasno',
'razlika_izgovoreno_hotword': 0.2222222222222222},
'glasovno5':
{'komanda': "subprocess.Popen(['amixer', 'set', 'Master', '10%-'])",
'hotword': 'smanji',
'razlika_izgovoreno_hotword': 0.2},
'glasovno6':
{'komanda': "subprocess.Popen(['amixer', 'set', 'Master', '10%+'])",
'hotword': 'poja\xc4\x8daj',
'razlika_izgovoreno_hotword': 0.0}