ftiiii commited on
Commit
4fb8941
·
verified ·
1 Parent(s): dae1166

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +67 -235
app.py CHANGED
@@ -1,246 +1,78 @@
1
- import gradio as gr
2
- import numpy as np
3
- import librosa
4
- import librosa.display
5
- import matplotlib
6
- matplotlib.use("Agg")
7
- import matplotlib.pyplot as plt
8
- import pywt
9
- import os
10
- import json
11
  import random
12
- import tempfile
13
- from PIL import Image
14
- from tensorflow.keras.models import load_model
15
- from sklearn.preprocessing import StandardScaler
16
-
17
- SAMPLE_RATE = 22050
18
- MAX_DURATION = 5
19
- TIME_STEPS = 20
20
- USE_DENOISE = True
21
-
22
- model = load_model("Huan_luyen_6_huhong.h5")
23
-
24
- def load_scaler_from_json(filepath):
25
- with open(filepath, 'r') as f:
26
- data = json.load(f)
27
- scaler = StandardScaler()
28
- scaler.mean_ = np.array(data['mean_'])
29
- scaler.scale_ = np.array(data['scale_'])
30
- scaler.n_features_in_ = len(scaler.mean_)
31
- return scaler
32
-
33
- scaler = load_scaler_from_json("scaler.json")
34
-
35
- with open("label_map.json", "r") as f:
36
- label_map = json.load(f)
37
- index_to_label = {v: k for k, v in label_map.items()}
38
-
39
- def denoise_wavelet(signal, wavelet='db8', level=4):
40
- coeffs = pywt.wavedec(signal, wavelet, level=level)
41
- sigma = np.median(np.abs(coeffs[-1])) / 0.6745
42
- uthresh = sigma * np.sqrt(2 * np.log(len(signal)))
43
- coeffs_denoised = [pywt.threshold(c, value=uthresh, mode='soft') for c in coeffs]
44
- return pywt.waverec(coeffs_denoised, wavelet)
45
-
46
- def create_sequences(mfcc, time_steps=20):
47
- return np.array([mfcc[i:i+time_steps] for i in range(len(mfcc) - time_steps)])
48
-
49
- def cat_2s_ngau_nhien(y, sr, duration=2):
50
- if len(y) < duration * sr:
51
- return y
52
- start = random.randint(0, len(y) - duration * sr)
53
- return y[start:start + duration * sr]
54
-
55
- def tao_anh_mel(file_path):
56
- y, sr = librosa.load(file_path, sr=None, mono=True)
57
- y = cat_2s_ngau_nhien(y, sr)
58
- S = librosa.feature.melspectrogram(y=y, sr=sr, n_mels=128)
59
- S_dB = librosa.power_to_db(S, ref=np.max)
60
- fig, ax = plt.subplots(figsize=(6, 3))
61
- img = librosa.display.specshow(S_dB, sr=sr, x_axis='time', y_axis='mel', ax=ax, cmap='magma')
62
- ax.set_title("Phổ tần Mel", fontsize=10)
63
- fig.colorbar(img, ax=ax)
64
- plt.tight_layout()
65
- path = os.path.join(tempfile.gettempdir(), "mel.png")
66
- fig.savefig(path, dpi=80)
67
- plt.close()
68
- return Image.open(path)
69
-
70
- def tao_wavelet_transform(file_path):
71
- y, sr = librosa.load(file_path, sr=None, mono=True)
72
- y = cat_2s_ngau_nhien(y, sr)
73
- coef, _ = pywt.cwt(y, scales=np.arange(1, 128), wavelet='morl', sampling_period=1/sr)
74
- fig, ax = plt.subplots(figsize=(6, 3))
75
- ax.imshow(np.abs(coef), extent=[0, len(y)/sr, 1, 128], cmap='plasma', aspect='auto', origin='lower')
76
- ax.set_title("Phổ sóng con (Wavelet)")
77
- ax.set_xlabel("Thời gian (s)")
78
- ax.set_ylabel("Tần số (scale)")
79
- plt.tight_layout()
80
- path = os.path.join(tempfile.gettempdir(), "wavelet.png")
81
- fig.savefig(path, dpi=80)
82
- plt.close()
83
- return Image.open(path)
84
-
85
- def tao_waveform_image(file_path):
86
- y, sr = librosa.load(file_path, sr=None, mono=True)
87
- y = cat_2s_ngau_nhien(y, sr)
88
- fig, ax = plt.subplots(figsize=(6, 2.5))
89
- librosa.display.waveshow(y, sr=sr, ax=ax, color='steelblue')
90
- ax.set_title("Biểu đồ Sóng Âm (Waveform)")
91
- ax.set_xlabel("Thời gian (s)")
92
- ax.set_ylabel("Biên độ")
93
- plt.tight_layout()
94
- path = os.path.join(tempfile.gettempdir(), "waveform.png")
95
- fig.savefig(path, dpi=80)
96
- plt.close()
97
- return Image.open(path)
98
-
99
- def bao_san_sang(file_path):
100
- if not file_path:
101
- return ""
102
- return "<b style='color:green;'>✅ Âm thanh đã sẵn sàng. Nhấn kiểm tra ngay!</b>"
103
-
104
- def sinh_anh(file_path):
105
- if not file_path:
106
- return None, None, None
107
- mel_img = tao_anh_mel(file_path)
108
- wavelet_img = tao_wavelet_transform(file_path)
109
- waveform_img = tao_waveform_image(file_path)
110
- return mel_img, wavelet_img, waveform_img
111
-
112
- def du_doan(file_path):
113
- if not file_path:
114
- return "<b style='color:red;'>❌ Chưa có âm thanh.</b>"
115
-
116
- signal, sr = librosa.load(file_path, sr=SAMPLE_RATE, mono=True)
117
- signal, _ = librosa.effects.trim(signal)
118
- signal = librosa.util.fix_length(signal, size=SAMPLE_RATE * MAX_DURATION)
119
-
120
- if USE_DENOISE:
121
- signal = denoise_wavelet(signal)
122
-
123
- mfcc = librosa.feature.mfcc(y=signal, sr=sr, n_mfcc=13).T
124
- mfcc = scaler.transform(mfcc)
125
- X_input = create_sequences(mfcc, time_steps=TIME_STEPS)
126
-
127
- if len(X_input) == 0:
128
- return "<b style='color:red;'>⚠️ Âm thanh quá ngắn để phân tích.</b>"
129
-
130
- y_preds = model.predict(X_input, verbose=0)
131
- avg_probs = np.mean(y_preds, axis=0)
132
- pred_index = np.argmax(avg_probs)
133
- confidence = avg_probs[pred_index] * 100
134
- pred_label = "HƯ HỎNG KHÁC" if confidence < 60 else index_to_label[pred_index]
135
-
136
- html = f"""<div style='background:#f0faff;color:#000;padding:10px;border-radius:10px'>
137
- <b style='color:#000'>📋 Kết Quả:</b><br>
138
- ✅ <b style='color:#000'>Tình trạng:</b> <span style='color:#007acc;font-size:18px'>{pred_label.upper()}</span><br>
139
- 📊 <b style='color:#000'>Độ tin cậy:</b> <span style='color:#000'>{confidence:.2f}%</span><br>
140
- <hr style='margin:6px 0'>
141
- <b style='color:#000'>Xác suất từng lớp:</b><br>"""
142
- for i, prob in enumerate(avg_probs):
143
- html += f"<span style='color:#000'>- {index_to_label[i]}: {prob*100:.1f}%</span><br>"
144
- html += "</div>"
145
- return html
146
-
147
- def reset_output():
148
- return "", None, None, None, ""
149
-
150
- def chon_file(f1, f2):
151
- return f1 if f1 else f2
152
-
153
- with gr.Blocks(css="""
154
- #check-btn {
155
- background: #007acc;
156
- color: white;
157
- height: 48px;
158
- font-size: 16px;
159
- font-weight: bold;
160
- border-radius: 10px;
161
- }
162
- """) as demo:
163
-
164
- gr.HTML("""
165
- <div style="
166
- display: flex;
167
- align-items: center;
168
- background-image: url('https://cdn-uploads.huggingface.co/production/uploads/6881f05ad0fc87fca019ee65/t7NwSiUHpjoFXh1S10MT4.png');
169
- background-repeat: no-repeat;
170
- background-size: 100px 40px;
171
- background-position: 0px 0px;
172
- padding-left: 60px;
173
- height: 50px;
174
- margin: 0;
175
- ">
176
- </div>
177
- """)
178
-
179
- gr.Markdown("""
180
- <div style='
181
- display: flex;
182
- justify-content: center;
183
- align-items: center;
184
- margin-top: -10px;
185
- margin-bottom: 10px;
186
- height: 40px;
187
- '>
188
- <h4 style='color:#007acc; font-size:20px; font-weight:bold; margin: 0;'>
189
- CHẨN ĐOÁN HƯ HỎNG TỪ ÂM THANH ĐỘNG CƠ
190
- </h4>
191
- </div>
192
- """)
193
 
194
  with gr.Row():
195
- audio_file = gr.Audio(type="filepath", label="📂 Tải File Âm Thanh", interactive=True)
196
- audio_mic = gr.Audio(type="filepath", label="🎤 Ghi Âm", sources=["microphone"], interactive=True)
197
-
198
- thong_bao_ready = gr.HTML()
199
- btn_check = gr.Button("🔍 KIỂM TRA NGAY", elem_id="check-btn")
200
- output_html = gr.HTML()
201
-
202
- with gr.Accordion("📊 Phân tích Âm Thanh", open=False):
203
- mel_output = gr.Image(label="")
204
- wavelet_output = gr.Image(label="")
205
- waveform_output = gr.Image(label="")
206
-
207
- def xu_ly_toan_bo(file_path):
208
- tb = bao_san_sang(file_path)
209
- mel, wavl, wave = sinh_anh(file_path)
210
- kq = du_doan(file_path)
211
- return tb, mel, wavl, wave, kq
212
-
213
- audio_file.change(
214
- fn=xu_ly_toan_bo,
215
- inputs=audio_file,
216
- outputs=[thong_bao_ready, mel_output, wavelet_output, waveform_output, output_html]
217
  )
218
 
219
- audio_mic.change(
220
- fn=xu_ly_toan_bo,
221
- inputs=audio_mic,
222
- outputs=[thong_bao_ready, mel_output, wavelet_output, waveform_output, output_html]
223
  )
224
 
225
- btn_check.click(
226
- fn=lambda f1, f2: du_doan(chon_file(f1, f2)),
227
- inputs=[audio_file, audio_mic],
228
- outputs=output_html
229
  )
230
 
231
- audio_file.clear(fn=reset_output, outputs=[
232
- thong_bao_ready,
233
- mel_output,
234
- wavelet_output,
235
- waveform_output,
236
- output_html
237
- ])
238
- audio_mic.clear(fn=reset_output, outputs=[
239
- thong_bao_ready,
240
- mel_output,
241
- wavelet_output,
242
- waveform_output,
243
- output_html
244
- ])
245
 
246
  demo.launch()
 
1
+ import gradio as gr
 
 
 
 
 
 
 
 
 
2
  import random
3
+
4
+ # Trạng thái game
5
+ def new_game():
6
+ return 0, 0, 1, "Game bắt đầu! ⚽"
7
+
8
+ def shoot(direction, score, round_num):
9
+ directions = ["trái", "giữa", "phải"]
10
+ keeper = random.choice(directions)
11
+
12
+ if direction == keeper:
13
+ result = f"❌ Bị cản! (Thủ môn: {keeper})"
14
+ else:
15
+ score += 1
16
+ result = f"⚽ GOAL!!! (Thủ môn: {keeper})"
17
+
18
+ round_num += 1
19
+
20
+ if round_num > 5:
21
+ result += f"\n\n🏁 Kết thúc! Bạn ghi {score}/5 bàn"
22
+
23
+ return score, round_num, result
24
+
25
+ # UI
26
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
27
+ gr.Markdown(
28
+ """
29
+ # ⚽ Penalty Game
30
+ ### Sút 5 quả - ghi càng nhiều bàn càng tốt!
31
+ """
32
+ )
33
+
34
+ score = gr.State(0)
35
+ round_num = gr.State(1)
36
+
37
+ score_text = gr.Markdown("**Điểm: 0 | Lượt: 1/5**")
38
+ result = gr.Markdown("Chọn hướng sút 👇")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  with gr.Row():
41
+ btn_left = gr.Button("⬅️ Trái")
42
+ btn_center = gr.Button("⬆️ Giữa")
43
+ btn_right = gr.Button("➡️ Phải")
44
+
45
+ btn_restart = gr.Button("🔄 Chơi lại")
46
+
47
+ def update_ui(score, round_num, message):
48
+ return (
49
+ score,
50
+ round_num,
51
+ f"**Điểm: {score} | Lượt: {min(round_num,5)}/5**",
52
+ message
53
+ )
54
+
55
+ btn_left.click(
56
+ lambda s, r: update_ui(*shoot("trái", s, r)),
57
+ inputs=[score, round_num],
58
+ outputs=[score, round_num, score_text, result]
 
 
 
 
59
  )
60
 
61
+ btn_center.click(
62
+ lambda s, r: update_ui(*shoot("giữa", s, r)),
63
+ inputs=[score, round_num],
64
+ outputs=[score, round_num, score_text, result]
65
  )
66
 
67
+ btn_right.click(
68
+ lambda s, r: update_ui(*shoot("phải", s, r)),
69
+ inputs=[score, round_num],
70
+ outputs=[score, round_num, score_text, result]
71
  )
72
 
73
+ btn_restart.click(
74
+ lambda: (0, 1, "**Điểm: 0 | Lượt: 1/5**", "Game mới! ⚽"),
75
+ outputs=[score, round_num, score_text, result]
76
+ )
 
 
 
 
 
 
 
 
 
 
77
 
78
  demo.launch()