GCLing commited on
Commit
0b5ee74
·
verified ·
1 Parent(s): 77ec4ba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -71
app.py CHANGED
@@ -1,89 +1,74 @@
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
- )
 
 
 
 
 
 
 
1
  # app.py
2
+
3
  import gradio as gr
4
  import numpy as np
5
+ import base64, io, os
6
+ import librosa, joblib
7
  from deepface import DeepFace
8
 
9
+ # —— 1. 预加载 DeepFace、语音模型 ——
10
+ # DeepFace 会自动把权重缓存到 DEEPFACE_HOME 下的 /weights
11
+ os.environ["DEEPFACE_HOME"] = "/tmp/.deepface"
12
+ def load_models():
13
+ # a) 热身 DeepFace
14
+ DeepFace.analyze(
15
+ img_path = np.zeros((224,224,3), dtype=np.uint8),
16
+ actions = ['emotion'],
 
 
 
 
 
 
17
  enforce_detection=False
18
  )
19
+ # b) 加载本地训练好的语音模型
20
+ return joblib.load("src/voice_model.joblib")
 
 
 
 
21
 
22
+ audio_model = load_models()
23
+
24
+ # —— 2. 文本情绪函数 ——
25
+ def analyze_text_fn(text):
26
+ if any(w in text for w in ["開心","快樂","愉快","喜悅","歡喜","興奮","歡","高興"]): return "😊 happy"
27
+ if any(w in text for w in ["生氣","憤怒","不爽","發火","火大","氣憤"]): return "😠 angry"
28
+ if any(w in text for w in ["傷心","難過","哭","難受","心酸","憂","悲","哀","痛苦","慘","愁"]): return "😢 sad"
29
+ if any(w in text for w in ["驚訝","意外","嚇","驚詫","詫異","訝異","好奇"]): return "😲 surprise"
30
+ if any(w in text for w in ["怕","恐懼","緊張","懼","膽怯","畏"]): return "😨 fear"
31
+ return "😐 neutral"
32
+
33
+ # —— 3. 语音情绪函数 ——
34
+ def analyze_audio_fn(wav_bytes):
35
+ y, sr = librosa.load(io.BytesIO(wav_bytes), sr=None)
36
  mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13)
37
  mf = np.mean(mfccs.T, axis=0)
38
  return audio_model.predict([mf])[0]
39
 
40
+ # —— 4. 人脸情绪函数 ——
41
+ def analyze_face_fn(img: np.ndarray):
42
+ res = DeepFace.analyze(
43
+ img, actions=['emotion'], enforce_detection=False
44
+ )
45
+ # 兼容 list/dict 返回
46
+ emo = res[0]['dominant_emotion'] if isinstance(res, list) else res['dominant_emotion']
47
+ return emo
 
 
48
 
49
+ # —— 5. 用 Gradio Blocks 组织界面 ——
50
+ with gr.Blocks() as demo:
51
  gr.Markdown("## 📱 多模態即時情緒分析")
 
52
  tabs = gr.Tabs()
 
 
 
 
 
 
 
 
 
 
53
 
54
+ with tabs.add_tab("🔴 Face(Browser→Webcam)"):
55
+ camera = gr.Image(source="webcam", tool="editor", label="對準你的臉")
56
+ out_face = gr.Textbox(label="偵測到的情緒")
57
+ camera.change(analyze_face_fn, camera, out_face)
 
 
 
58
 
59
+ with tabs.add_tab("🎤 上傳 WAV 檔"):
60
+ wav = gr.File(label="上傳 .wav")
61
+ out_audio = gr.Textbox(label="語音檢測情緒")
62
+ wav.upload(analyze_audio_fn, wav, out_audio)
 
 
 
 
63
 
64
+ with tabs.add_tab("⌨️ 輸入文字"):
65
+ txt = gr.Textbox(label="在此輸入文字")
66
+ btn = gr.Button("開始分析")
67
+ out_text = gr.Textbox(label="文字檢測情緒")
68
+ btn.click(analyze_text_fn, txt, out_text)
69
+
70
+ gr.Markdown("---")
71
+ gr.Markdown("ℹ️ 內建 DeepFace、librosa & sklearn 進行多模態情緒分析")
72
+
73
+ if __name__ == "__main__":
74
+ demo.launch()