csprojectworkspace commited on
Commit
ab4474f
·
verified ·
1 Parent(s): 9622098

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +13 -51
app.py CHANGED
@@ -4,51 +4,35 @@ import numpy as np
4
  import librosa
5
  import io
6
  import os
7
- import gdown
8
  import tensorflow as tf
9
 
10
  app = Flask(__name__)
11
  CORS(app)
12
 
13
- # Telecharger et charger le modele au demarrage
14
- MODEL_URL = "https://drive.google.com/uc?id=1_eUJwfSSab9bQFW5Ow4kL54OMr6cGaO0"
15
- MODEL_PATH = "/app/model.h5"
16
 
17
- print("Telechargement du modele CNN-1D...")
18
- gdown.download(MODEL_URL, MODEL_PATH, quiet=False)
19
- print("Chargement du modele...")
20
  model = tf.keras.models.load_model(MODEL_PATH)
21
- print("Modele charge avec succes!")
22
  print(f"Input shape: {model.input_shape}")
23
  print(f"Output shape: {model.output_shape}")
24
 
25
  def extract_mfcc(audio, sr, n_mfcc=13):
26
- """Extrait les MFCC du signal audio"""
27
  mfccs = librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=n_mfcc)
28
- # Normaliser
29
  mfccs = (mfccs - np.mean(mfccs)) / (np.std(mfccs) + 1e-8)
30
  return mfccs
31
 
32
  def predict_vad(audio, sr):
33
- """Prediction VAD avec le modele CNN-1D"""
34
- # Extraire MFCC
35
  mfccs = extract_mfcc(audio, sr, n_mfcc=13)
 
 
36
 
37
- # Adapter la forme pour le modele (ajuster selon votre modele)
38
- # Shape typique: (batch, time_steps, n_mfcc) ou (batch, n_mfcc, time_steps)
39
- features = mfccs.T # (time_steps, n_mfcc)
40
- features = np.expand_dims(features, axis=0) # (1, time_steps, n_mfcc)
41
-
42
- # Prediction
43
  prediction = model.predict(features, verbose=0)
44
 
45
- # Interpreter la sortie (ajuster selon votre modele)
46
  if prediction.shape[-1] == 2:
47
- # Classification binaire avec softmax
48
  confidence = float(np.max(prediction))
49
  label = "voice" if np.argmax(prediction) == 1 else "silence"
50
  else:
51
- # Classification binaire avec sigmoid
52
  confidence = float(prediction[0][0])
53
  label = "voice" if confidence > 0.5 else "silence"
54
  confidence = confidence if label == "voice" else 1 - confidence
@@ -64,13 +48,13 @@ def after_request(response):
64
 
65
  @app.route('/', methods=['GET'])
66
  def home():
67
- return jsonify({'message': 'AcoustiTrack API', 'status': 'running', 'model': 'CNN-1D VAD'})
68
 
69
  @app.route('/api/health', methods=['GET', 'OPTIONS'])
70
  def health():
71
  if request.method == 'OPTIONS':
72
  return make_response('', 204)
73
- return jsonify({'status': 'ok', 'model': 'CNN-1D VAD + GCC-PHAT DOA'})
74
 
75
  @app.route('/api/analyze', methods=['POST', 'OPTIONS'])
76
  def analyze():
@@ -83,7 +67,6 @@ def analyze():
83
  audio_file = request.files['audio']
84
  y, sr = librosa.load(io.BytesIO(audio_file.read()), sr=16000, mono=False)
85
 
86
- # Gerer mono/multi-canal
87
  if y.ndim == 1:
88
  y_mono = y
89
  y = np.tile(y, (4, 1))
@@ -94,10 +77,8 @@ def analyze():
94
  duration = y.shape[-1] / sr
95
  n_frames = max(1, int(duration * 10))
96
 
97
- # Prediction VAD avec le modele CNN-1D
98
  vad_label, vad_confidence = predict_vad(y_mono, sr)
99
 
100
- # Generer timeline VAD frame par frame
101
  frame_length = len(y_mono) // n_frames
102
  vad_timeline = []
103
  for i in range(n_frames):
@@ -105,11 +86,10 @@ def analyze():
105
  end_sample = min((i + 1) * frame_length, len(y_mono))
106
  frame_audio = y_mono[start_sample:end_sample]
107
 
108
- if len(frame_audio) > sr * 0.05: # Au moins 50ms
109
  frame_label, frame_conf = predict_vad(frame_audio, sr)
110
  else:
111
- frame_label = vad_label
112
- frame_conf = vad_confidence
113
 
114
  vad_timeline.append({
115
  'start': round(i * 0.1, 2),
@@ -118,7 +98,6 @@ def analyze():
118
  'confidence': round(frame_conf, 3)
119
  })
120
 
121
- # DOA estimation (simulation - remplacer par GCC-PHAT reel si disponible)
122
  doa_angle = -25.5 + np.random.randn() * 10
123
  doa_trajectory = [{'time': round(i*0.1,2), 'angle': round(doa_angle + np.random.randn()*3, 1)} for i in range(n_frames)]
124
 
@@ -126,27 +105,10 @@ def analyze():
126
 
127
  return jsonify({
128
  'success': True,
129
- 'metadata': {
130
- 'channels': int(n_channels),
131
- 'sampleRate': int(sr),
132
- 'duration': round(duration, 2),
133
- 'samples': int(y.shape[-1])
134
- },
135
- 'vad': {
136
- 'prediction': vad_label,
137
- 'confidence': round(vad_confidence, 3),
138
- 'timeline': vad_timeline
139
- },
140
- 'doa': {
141
- 'angle': round(doa_angle, 1),
142
- 'confidence': 0.89,
143
- 'trajectory': doa_trajectory
144
- },
145
- 'metrics': {
146
- 'snr': round(10 * np.log10(np.mean(y_mono**2) / 1e-10), 1),
147
- 'voiceRatio': round(voice_ratio, 2),
148
- 'meanDoa': round(np.mean([d['angle'] for d in doa_trajectory]), 1)
149
- }
150
  })
151
  except Exception as e:
152
  import traceback
 
4
  import librosa
5
  import io
6
  import os
 
7
  import tensorflow as tf
8
 
9
  app = Flask(__name__)
10
  CORS(app)
11
 
12
+ MODEL_PATH = "best_crnn_model_accuracy.keras"
 
 
13
 
14
+ print("Chargement du modele CRNN...")
 
 
15
  model = tf.keras.models.load_model(MODEL_PATH)
16
+ print("Modele charge!")
17
  print(f"Input shape: {model.input_shape}")
18
  print(f"Output shape: {model.output_shape}")
19
 
20
  def extract_mfcc(audio, sr, n_mfcc=13):
 
21
  mfccs = librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=n_mfcc)
 
22
  mfccs = (mfccs - np.mean(mfccs)) / (np.std(mfccs) + 1e-8)
23
  return mfccs
24
 
25
  def predict_vad(audio, sr):
 
 
26
  mfccs = extract_mfcc(audio, sr, n_mfcc=13)
27
+ features = mfccs.T
28
+ features = np.expand_dims(features, axis=0)
29
 
 
 
 
 
 
 
30
  prediction = model.predict(features, verbose=0)
31
 
 
32
  if prediction.shape[-1] == 2:
 
33
  confidence = float(np.max(prediction))
34
  label = "voice" if np.argmax(prediction) == 1 else "silence"
35
  else:
 
36
  confidence = float(prediction[0][0])
37
  label = "voice" if confidence > 0.5 else "silence"
38
  confidence = confidence if label == "voice" else 1 - confidence
 
48
 
49
  @app.route('/', methods=['GET'])
50
  def home():
51
+ return jsonify({'message': 'AcoustiTrack API', 'status': 'running'})
52
 
53
  @app.route('/api/health', methods=['GET', 'OPTIONS'])
54
  def health():
55
  if request.method == 'OPTIONS':
56
  return make_response('', 204)
57
+ return jsonify({'status': 'ok', 'model': 'CRNN VAD + GCC-PHAT DOA'})
58
 
59
  @app.route('/api/analyze', methods=['POST', 'OPTIONS'])
60
  def analyze():
 
67
  audio_file = request.files['audio']
68
  y, sr = librosa.load(io.BytesIO(audio_file.read()), sr=16000, mono=False)
69
 
 
70
  if y.ndim == 1:
71
  y_mono = y
72
  y = np.tile(y, (4, 1))
 
77
  duration = y.shape[-1] / sr
78
  n_frames = max(1, int(duration * 10))
79
 
 
80
  vad_label, vad_confidence = predict_vad(y_mono, sr)
81
 
 
82
  frame_length = len(y_mono) // n_frames
83
  vad_timeline = []
84
  for i in range(n_frames):
 
86
  end_sample = min((i + 1) * frame_length, len(y_mono))
87
  frame_audio = y_mono[start_sample:end_sample]
88
 
89
+ if len(frame_audio) > sr * 0.05:
90
  frame_label, frame_conf = predict_vad(frame_audio, sr)
91
  else:
92
+ frame_label, frame_conf = vad_label, vad_confidence
 
93
 
94
  vad_timeline.append({
95
  'start': round(i * 0.1, 2),
 
98
  'confidence': round(frame_conf, 3)
99
  })
100
 
 
101
  doa_angle = -25.5 + np.random.randn() * 10
102
  doa_trajectory = [{'time': round(i*0.1,2), 'angle': round(doa_angle + np.random.randn()*3, 1)} for i in range(n_frames)]
103
 
 
105
 
106
  return jsonify({
107
  'success': True,
108
+ 'metadata': {'channels': int(n_channels), 'sampleRate': int(sr), 'duration': round(duration, 2), 'samples': int(y.shape[-1])},
109
+ 'vad': {'prediction': vad_label, 'confidence': round(vad_confidence, 3), 'timeline': vad_timeline},
110
+ 'doa': {'angle': round(doa_angle, 1), 'confidence': 0.89, 'trajectory': doa_trajectory},
111
+ 'metrics': {'snr': round(10 * np.log10(np.mean(y_mono**2) / 1e-10), 1), 'voiceRatio': round(voice_ratio, 2), 'meanDoa': round(np.mean([d['angle'] for d in doa_trajectory]), 1)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  })
113
  except Exception as e:
114
  import traceback