preparation intégration reconaissance vocale

This commit is contained in:
Quentin Roussel
2023-03-23 09:53:16 +01:00
parent bc0270b707
commit e097c1fd23
13 changed files with 87 additions and 32 deletions

View File

@@ -1,4 +1,4 @@
FROM python:3.8-slim FROM python:3.8
#Ne pas créer les fichiers .pyc #Ne pas créer les fichiers .pyc
ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONDONTWRITEBYTECODE=1
@@ -7,7 +7,7 @@ ENV PYTHONUNBUFFERED=1
#Installation des dépendances de opencv #Installation des dépendances de opencv
RUN apt-get update RUN apt-get update
RUN apt-get install ffmpeg libsm6 libxext6 -y RUN apt-get install ffmpeg libsm6 libxext6 portaudio19-dev python3-pyaudio -y
# Installation des dépendances python # Installation des dépendances python
COPY requirements.txt . COPY requirements.txt .

View File

@@ -5,6 +5,7 @@ import math
from scipy.io import wavfile from scipy.io import wavfile
import wave import wave
from scipy.fftpack import fft,dct from scipy.fftpack import fft,dct
import time
from matplotlib.patches import ConnectionPatch from matplotlib.patches import ConnectionPatch
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
@@ -170,31 +171,38 @@ def record_audio(filename, duration, sr):
print(f"Fichier enregistré sous {filename}") print(f"Fichier enregistré sous {filename}")
def coupe_silence(signal): def coupe_silence(signal):
t = 0 t = 0
if signal[t] == 0 : if signal[t] == 0 :
p = 0 p = 0
while signal[t+p] == 0 : while signal[t+p] == 0 :
if p == 88 : if p == 88 :
signal = signal[:t] + signal[t+p:] signal = signal[:t] + signal[t+p:]
coupe_silence(signal) coupe_silence(signal)
else : else :
p = p+1 p = p+1
#Todo : detecte si pas de note donnée
def get_grade():
######## TEST DEBUG ########
time.sleep(6)
return 5
sr = 44100 # fréquence d'échantillonnage sr = 44100 # fréquence d'échantillonnage
duration = 6 # durée d'enregistrement en secondes duration = 6 # durée d'enregistrement en secondes
filename = "audio_query" # nom du fichier à enregistrer filename = "recording" # nom du fichier à enregistrer
data_dir = "audio_data/"
record_audio(filename, duration, sr) record_audio(filename, duration, sr)
audio_query, sr = librosa.load('C:\\Users\\HP\\audio_query.wav', sr=sr) audio_query, sr = librosa.load(f'{filename}.wav', sr=sr)
coupe_silence(audio_query) coupe_silence(audio_query)
audio_train_list = [librosa.load('C:\\Users\\HP\\Documents\\cool.wav', sr=sr)[0], librosa.load('C:\\Users\\HP\\Documents\\formidable.wav', sr=sr)[0], librosa.load('C:\\Users\\HP\\Documents\\cest mauvais.wav', sr=sr)[0] , librosa.load('C:\\Users\\HP\\Documents\\un.wav', sr=sr)[0], librosa.load('C:\\Users\\HP\\Documents\\parfait.wav', sr=sr)[0]] training_file_names = []
for path in os.listdir(data_dir):
if os.path.isfile(os.path.join(data_dir, path)):
training_file_names.append(data_dir + path)
print(training_file_names)
audio_train_list = [librosa.load(file, sr=sr)[0] for file in training_file_names]
recognized_word_index = recognize_speech(audio_query, audio_train_list, sr) recognized_word_index = recognize_speech(audio_query, audio_train_list, sr)
print(f'Recognized word: {recognized_word_index}') print(f'Recognized word: {recognized_word_index}')
return recognized_word_index
print(get_grade())

View File

@@ -1,4 +1,5 @@
from hand_detector import HandDetector from hand_detector import HandDetector
from audio_detector import get_grade
from network import WebsocketServer from network import WebsocketServer
import time import time
@@ -6,11 +7,13 @@ import time
class Manager(): class Manager():
def __init__(self): def __init__(self):
self.state = 0 self.state = 0
self.avis = { self.defualtAvis = {
"note": None, "note": None,
"commentaire": None, "commentaire": None,
"notes_autres": {} "notes_autres": {}
} }
self.avis = self.defualtAvis
self.server = WebsocketServer(None) self.server = WebsocketServer(None)
self.server.start() self.server.start()
self.handDetector = HandDetector() self.handDetector = HandDetector()
@@ -23,16 +26,30 @@ class Manager():
self.sleep() self.sleep()
if(self.state == 1): if(self.state == 1):
self.camera() self.camera()
if(self.state == 2):
self.audio()
if(self.state == 3):
self.thankYou()
time.sleep(0.01) time.sleep(0.01)
#Fonction qui est executée pendant que la borne est en veille, reveille la borne si une main est detectée #Fonction qui est executée pendant que la borne est en veille, reveille la borne si une main est detectée
def sleep(self): def sleep(self):
res = self.handDetector.detect() res = self.handDetector.detect()
print(res)
if(res != False): if(res != False):
self.state = 1 self.state = 1
self.server.sendMessage({"type": "state", "state": 1}) self.server.sendMessage({"type": "state", "state": 1})
def audio(self):
grade = get_grade()
if(grade != False):
self.server.sendMessage({"type":"new_grade","grade":grade})
self.avis["notes_autres"]["test"] = grade
time.sleep(3)
self.state = 2
self.server.sendMessage({"type": "state", "state": 3})
#Envoie la position de la main a l'écran et passe a l'étape suivante si une main est detectée pendant assez longtemps #Envoie la position de la main a l'écran et passe a l'étape suivante si une main est detectée pendant assez longtemps
def camera(self): def camera(self):
res = self.handDetector.detect() res = self.handDetector.detect()
@@ -44,5 +61,10 @@ class Manager():
self.state = 2 self.state = 2
self.server.sendMessage({"type": "state", "state": 2}) self.server.sendMessage({"type": "state", "state": 2})
def thankYou(self):
time.sleep(10)
self.state = 0
self.server.sendMessage({"type": "state", "state": 0})
self.sendReview()
self.avis = self.defualtAvis

View File

@@ -29,3 +29,9 @@ class WebsocketServer(threading.Thread):
def sendMessage(self,message): def sendMessage(self,message):
self.messageQueue.append(message) self.messageQueue.append(message)
class ApiClient():
def __init__(self, host=os.getenv("API_HOST"), port=os.getenv("API_PORT")):
self.host = host
self.port = port

Binary file not shown.

View File

@@ -3,3 +3,6 @@ requests
opencv-python opencv-python
mediapipe mediapipe
numpy numpy
pyaudio
librosa
scipy

View File

@@ -39,6 +39,8 @@ services:
#API de gestion des avis, permet d'ajouter ou de récuperer des avis ou les stats sur les avis par des requêtes HTTP #API de gestion des avis, permet d'ajouter ou de récuperer des avis ou les stats sur les avis par des requêtes HTTP
reviews_api: reviews_api:
container_name: reviews_api container_name: reviews_api
expose:
- 8080
ports: ports:
- 8080:8080 - 8080:8080
environment: environment:
@@ -73,11 +75,11 @@ services:
- 800:80 - 800:80
#Formulaire de retour d'avis #Formulaire de retour d'avis
Formulaire: formulaire:
image: httpd:latest image: httpd:latest
volumes: volumes:
- ./Formulaire:/usr/local/apache2/htdocs/ - ./formulaire:/usr/local/apache2/htdocs/
container_name: Formulaire container_name: formulaire
ports: ports:
- 80:80 - 80:80
# #Backend de la borne : scripts pythons de reconnaissances video et audio # #Backend de la borne : scripts pythons de reconnaissances video et audio
@@ -92,6 +94,8 @@ services:
environment: environment:
- PORT=5000 - PORT=5000
- HOST=backend_reconnaissance - HOST=backend_reconnaissance
- API_HOST=reviews_api
- API_PORT=8080
ports: ports:
#Ce container est le serveur websocker dont le client est l'interface de la borne qui tourne dans le navigateur #Ce container est le serveur websocker dont le client est l'interface de la borne qui tourne dans le navigateur
- 5000:5000 - 5000:5000

View File

@@ -49,3 +49,8 @@ html, body {
.instructions > .title { .instructions > .title {
border-bottom: 3px #6B8000 solid; border-bottom: 3px #6B8000 solid;
} }
.instructions > table, .instructions > th,.instructions > td {
border: 1px solid #6B8000;
border-collapse: collapse;
}

View File

@@ -8,4 +8,10 @@ class AudioPage {
this.isEnabled = isEnabled; this.isEnabled = isEnabled;
this.DOMElement.style.display = isEnabled ? "block" : "none"; this.DOMElement.style.display = isEnabled ? "block" : "none";
} }
setGrade(grade) {
if(this.isEnabled) {
this.DOMElement.getElementById("grade").innerHTML = grade.toString();
}
}
} }

View File

@@ -1,5 +1,5 @@
class WebsocketClient { class WebsocketClient {
constructor(onNewEffects, onNewGrade, onNewState) { constructor(onNewEffects, onNewState, onNewGrade) {
this.socket = new WebSocket("ws://localhost:5000"); this.socket = new WebSocket("ws://localhost:5000");
this.socket.addEventListener("open", (event) => { this.socket.addEventListener("open", (event) => {
this.socket.send("connected"); this.socket.send("connected");

View File

@@ -18,7 +18,8 @@ class StateManager {
this.setState(STATE.video); this.setState(STATE.video);
this._cameraPage.setEffects(effects) this._cameraPage.setEffects(effects)
}, },
(state) => this.setState(state) (state) => this.setState(state),
(grade) => this._audioPage.setGrade(grade)
); );
this._sleepingPage.enabled = true; this._sleepingPage.enabled = true;

View File

@@ -35,7 +35,7 @@
<div class="title"> <div class="title">
<h1>Enregistrement audio blabal</h1> <h1>Enregistrement audio blabal</h1>
</div> </div>
<p>Prononcez à voix haute les notes correspondant aux critères suivants dans l'ordre</p> <p>Donnez une note sur 10 au critère suivant</p>
<table> <table>
<tr> <tr>
<th>Critère</td> <th>Critère</td>
@@ -43,7 +43,7 @@
</tr> </tr>
<tr> <tr>
<td>Calme</td> <td>Calme</td>
<td> /10</td> <td> <span id="grade"></span>/10</td>
</tr> </tr>
</table> </table>
</div> </div>

Binary file not shown.