GCLing commited on
Commit
7caecfb
·
verified ·
1 Parent(s): eb9d50b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -27
app.py CHANGED
@@ -1,61 +1,77 @@
 
 
 
 
 
 
1
  import gradio as gr
2
  import numpy as np
3
- import joblib, io, base64
4
  import librosa
5
  from deepface import DeepFace
6
 
7
- # —— 1. 載入模型 ——
8
- # 如果只要上傳 wav/text,就先把 face 部分包在 fn 裡動態 load
9
- audio_model = joblib.load("src/voice_model.joblib")
 
10
 
 
11
  def analyze_face(frame: np.ndarray):
12
  # DeepFace 回傳 dict,裡面有 'dominant_emotion'
13
  res = DeepFace.analyze(frame, actions=["emotion"], enforce_detection=False)
14
- emo = res["dominant_emotion"]
15
- return frame, emo
16
 
17
  def analyze_audio(wav_file):
18
  wav_bytes = wav_file.read()
 
19
  y, sr = librosa.load(io.BytesIO(wav_bytes), sr=None)
20
  mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)
21
  mf = np.mean(mfccs.T, axis=0)
22
  return audio_model.predict([mf])[0]
23
 
24
  def analyze_text(txt):
 
25
  mapping = {
26
- "😊happy":["開心","快樂","愉快","喜悅","歡喜","興奮","","高興"],
27
- "😠angry": ["生氣","憤怒","不爽","發火","火大","氣憤"],
28
- "😢sad": ["傷心","難過","哭","難受","心酸","","悲","哀","痛苦","慘","愁"],
29
- "😲surprise": ["驚訝","意外","嚇","驚詫","詫異","訝異","好奇"],
30
- "😨fear": ["怕","恐懼","緊張","懼","膽怯","畏"],
31
  }
32
  for emo, kws in mapping.items():
33
  if any(w in txt for w in kws):
34
  return emo
35
- return "neutral"
36
 
37
- with gr.Blocks() as demo:
38
- gr.Markdown("## 多模態即時情緒分析")
 
39
  with gr.Tabs():
40
  with gr.TabItem("📷 Live Face"):
41
- from gradio import components as grc
42
-
43
- camera = grc.Camera(label="請對準鏡頭")
44
-
45
- out_img = gr.Image(label="畫面")
46
- out_label = gr.Label(label="情緒")
47
- camera.change(fn=analyze_face, inputs=camera, outputs=[out_img, out_label], live=True)
 
 
 
48
 
49
- with gr.TabItem("🎤 上傳語音"):
50
- wav = gr.File(label="選擇 .wav ", file_types=[".wav"])
51
- wav_btn = gr.Button("分析")
52
- wav_out = gr.Text(label="偵測到的情緒")
53
  wav_btn.click(fn=analyze_audio, inputs=wav, outputs=wav_out)
54
 
55
  with gr.TabItem("⌨️ 輸入文字"):
56
  txt = gr.Textbox(label="在此輸入文字", lines=3)
57
- txt_btn = gr.Button("分析")
58
- txt_out = gr.Text(label="偵測到的情緒")
59
  txt_btn.click(fn=analyze_text, inputs=txt, outputs=txt_out)
60
 
 
 
 
61
  demo.launch()
 
1
+ # app.py
2
+ import os
3
+ # ─── 解決 DeepFace 無法寫入預設路徑的問題 ─────────────────────────────────────────
4
+ # 將 DeepFace 的快取目錄指向可寫入的 /tmp 之下
5
+ os.environ["DEEPFACE_HOME"] = "/tmp/.deepface"
6
+
7
  import gradio as gr
8
  import numpy as np
9
+ import joblib, io
10
  import librosa
11
  from deepface import DeepFace
12
 
13
+ # ─── 1. 載入模型 ─────────────────────────────────────────────────────────────
14
+ # 我們把模型檔放在跟 app.py 同一層的 voice_model.joblib
15
+ MODEL_PATH = os.path.join(os.path.dirname(__file__), "voice_model.joblib")
16
+ audio_model = joblib.load(MODEL_PATH)
17
 
18
+ # ─── 2. 定義各種分析函數 ────────────────────────────────────────────────────
19
  def analyze_face(frame: np.ndarray):
20
  # DeepFace 回傳 dict,裡面有 'dominant_emotion'
21
  res = DeepFace.analyze(frame, actions=["emotion"], enforce_detection=False)
22
+ return frame, res["dominant_emotion"]
 
23
 
24
  def analyze_audio(wav_file):
25
  wav_bytes = wav_file.read()
26
+ # 用 librosa 讀入
27
  y, sr = librosa.load(io.BytesIO(wav_bytes), sr=None)
28
  mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)
29
  mf = np.mean(mfccs.T, axis=0)
30
  return audio_model.predict([mf])[0]
31
 
32
  def analyze_text(txt):
33
+ # 簡單關鍵字 mapping
34
  mapping = {
35
+ "😊 happy": ["開心","快樂","愉快","喜悅","歡喜","興奮","高興",""],
36
+ "😠 angry": ["生氣","憤怒","不爽","發火","火大","氣憤"],
37
+ "😢 sad": ["傷心","難過","哭","","","心酸","哀","痛苦","慘","愁"],
38
+ "😲 surprise":["驚訝","意外","嚇","好奇","驚詫","詫異","訝異"],
39
+ "😨 fear": ["怕","恐懼","緊張","懼","膽怯","畏"],
40
  }
41
  for emo, kws in mapping.items():
42
  if any(w in txt for w in kws):
43
  return emo
44
+ return "😐 neutral"
45
 
46
+ # ─── 3. 建立 Gradio 介面 ────────────────────────────────────────────────────
47
+ with gr.Blocks(title="多模態即時情緒分析") as demo:
48
+ gr.Markdown("## 🤖 多模態即時情緒分析")
49
  with gr.Tabs():
50
  with gr.TabItem("📷 Live Face"):
51
+ # 注意要用 gr.components.Camera gr.components…
52
+ camera = gr.components.Camera(label="請對準鏡頭 (Live)")
53
+ out_img = gr.Image(label="擷取畫面")
54
+ out_lbl = gr.Label(label="檢測到的情緒")
55
+ camera.change(
56
+ fn=analyze_face,
57
+ inputs=camera,
58
+ outputs=[out_img, out_lbl],
59
+ live=True
60
+ )
61
 
62
+ with gr.TabItem("🎤 上傳語音檔"):
63
+ wav = gr.File(label="選擇 .wav 檔案", file_types=[".wav"])
64
+ wav_btn = gr.Button("開始分析")
65
+ wav_out = gr.Textbox(label="語音偵測到的情緒")
66
  wav_btn.click(fn=analyze_audio, inputs=wav, outputs=wav_out)
67
 
68
  with gr.TabItem("⌨️ 輸入文字"):
69
  txt = gr.Textbox(label="在此輸入文字", lines=3)
70
+ txt_btn = gr.Button("開始分析")
71
+ txt_out = gr.Textbox(label="文字偵測到的情緒")
72
  txt_btn.click(fn=analyze_text, inputs=txt, outputs=txt_out)
73
 
74
+ # 啟動
75
+ if __name__ == "__main__":
76
+ # Hugging Face Spaces 上不需要傳 host/port,直接 .launch() 即可
77
  demo.launch()