GCLing commited on
Commit
a2a4ab6
·
verified ·
1 Parent(s): cc857da

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -22
app.py CHANGED
@@ -1,40 +1,89 @@
1
  # app.py
2
- import os
3
- # —— 把 DeepFace 缓存目录指向可写的 /tmp/.deepface
4
- os.environ["DEEPFACE_HOME"] = "/tmp/.deepface"
5
- os.makedirs(os.environ["DEEPFACE_HOME"], exist_ok=True)
6
-
7
  import gradio as gr
8
- import cv2
9
  import numpy as np
 
 
10
  from deepface import DeepFace
11
 
12
- def face_emotion(frame: np.ndarray) -> str:
 
 
 
 
 
13
  """
14
- 接收 gr.Camera 给出的 RGB ndarray,
15
- 转成 BGR 后交给 DeepFace 分析情绪。
16
  """
17
- # RGB → BGR
18
- bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
19
  res = DeepFace.analyze(
20
- bgr,
21
  actions=['emotion'],
22
  enforce_detection=False
23
  )
24
- # DeepFace 支持 list 或 dict 返回
25
  if isinstance(res, list):
26
  emo = res[0].get('dominant_emotion', 'unknown')
27
  else:
28
  emo = res.get('dominant_emotion', 'unknown')
29
  return emo
30
 
31
- # —— Gradio 前端 ——
32
- with gr.Blocks() as demo:
33
- gr.Markdown("## 📱 多模態即時情緒分析(示範:即時人臉情緒)")
34
- camera = gr.Camera(label="請對準鏡頭", type="numpy")
35
- output = gr.Textbox(label="偵測到的情緒")
36
- # 实时流:fps 可以调低一点,减轻服务器压力
37
- camera.stream(face_emotion, camera, output, fps=5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- if __name__ == "__main__":
40
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # app.py
 
 
 
 
 
2
  import gradio as gr
 
3
  import numpy as np
4
+ import joblib, io
5
+ import librosa
6
  from deepface import DeepFace
7
 
8
+ # —— 1. 预加载模型 ——
9
+ # DeepFace 热身 + 载入语音模型
10
+ audio_model = joblib.load("src/voice_model.joblib")
11
+ # 你也可以包一层 try/except
12
+
13
+ def analyze_face(frame: np.ndarray):
14
  """
15
+ 输入:摄像头采到的 RGB numpy 数组
16
+ 输出:DeepFace 分析出的 dominant_emotion(字符串)
17
  """
18
+ # DeepFace.analyze 接受 RGB np.array
 
19
  res = DeepFace.analyze(
20
+ img_path=frame,
21
  actions=['emotion'],
22
  enforce_detection=False
23
  )
24
+ # 兼容 dict / list 返回
25
  if isinstance(res, list):
26
  emo = res[0].get('dominant_emotion', 'unknown')
27
  else:
28
  emo = res.get('dominant_emotion', 'unknown')
29
  return emo
30
 
31
+ def analyze_audio(wav_file):
32
+ """
33
+ 输入:上传的 wav(二进制)
34
+ 输出:语音情绪分类标签
35
+ """
36
+ data = wav_file.read()
37
+ y, sr = librosa.load(io.BytesIO(data), sr=None)
38
+ mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)
39
+ mf = np.mean(mfccs.T, axis=0)
40
+ return audio_model.predict([mf])[0]
41
+
42
+ def analyze_text(txt):
43
+ """
44
+ 简单的基于关键词的中文情绪分析
45
+ """
46
+ if any(w in text for w in ["開心","快樂","愉快","喜悅","歡喜","興奮","歡","高興"]): return "happy"
47
+ if any(w in text for w in ["生氣","憤怒","不爽","發火","火大","氣憤"]): return "angry"
48
+ if any(w in text for w in ["傷心","難過","哭","難受","心酸","憂","悲","哀","痛苦","慘","愁"]): return "sad"
49
+ if any(w in text for w in ["驚訝","意外","嚇","驚詫","詫異","訝異","好奇"]): return "surprise"
50
+ if any(w in text for w in ["怕","恐懼","緊張","懼","膽怯","畏"]): return "fear"
51
+ return "neutral"
52
+
53
+ with gr.Blocks(title="多模態即時情緒分析") as demo:
54
+ gr.Markdown("## 📱 多模態即時情緒分析")
55
+
56
+ tabs = gr.Tabs()
57
+ with tabs:
58
+ with gr.TabItem("🔴 Face(即時)"):
59
+ gr.Markdown("⚠️ Spaces 無法直接打開攝像頭,請本機 `python app.py` 測試;手機/電腦瀏覽器可用以下方式:")
60
+ camera = gr.Image(
61
+ source="webcam",
62
+ type="numpy",
63
+ label="請對準鏡頭"
64
+ )
65
+ face_out = gr.Textbox(label="偵測結果")
66
+ camera.change(fn=analyze_face, inputs=camera, outputs=face_out)
67
 
68
+ with gr.TabItem("🎤 上傳語音"):
69
+ wav = gr.File(
70
+ label="請選擇 .wav 音檔",
71
+ file_types=["wav"]
72
+ )
73
+ audio_out = gr.Textbox(label="偵測結果")
74
+ wav.upload(fn=analyze_audio, inputs=wav, outputs=audio_out)
75
+
76
+ with gr.TabItem("⌨️ 文本輸入"):
77
+ txt = gr.Textbox(
78
+ label="在此輸入文字",
79
+ placeholder="輸入想要分析的句子…"
80
+ )
81
+ text_btn = gr.Button("開始分析")
82
+ text_out = gr.Textbox(label="偵測結果")
83
+ text_btn.click(fn=analyze_text, inputs=txt, outputs=text_out)
84
+
85
+ demo.launch(
86
+ server_name="0.0.0.0",
87
+ server_port=7860,
88
+ share=False
89
+ )