Spaces:
Configuration error
Configuration error
# app.py | |
import gradio as gr | |
import numpy as np | |
import joblib, io | |
import librosa | |
from deepface import DeepFace | |
# —— 1. 预加载模型 —— | |
# DeepFace 热身 + 载入语音模型 | |
audio_model = joblib.load("src/voice_model.joblib") | |
# 你也可以包一层 try/except | |
def analyze_face(frame: np.ndarray): | |
""" | |
输入:摄像头采到的 RGB numpy 数组 | |
输出:DeepFace 分析出的 dominant_emotion(字符串) | |
""" | |
# DeepFace.analyze 接受 RGB np.array | |
res = DeepFace.analyze( | |
img_path=frame, | |
actions=['emotion'], | |
enforce_detection=False | |
) | |
# 兼容 dict / list 返回 | |
if isinstance(res, list): | |
emo = res[0].get('dominant_emotion', 'unknown') | |
else: | |
emo = res.get('dominant_emotion', 'unknown') | |
return emo | |
def analyze_audio(wav_file): | |
""" | |
输入:上传的 wav(二进制) | |
输出:语音情绪分类标签 | |
""" | |
data = wav_file.read() | |
y, sr = librosa.load(io.BytesIO(data), sr=None) | |
mfccs = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=13) | |
mf = np.mean(mfccs.T, axis=0) | |
return audio_model.predict([mf])[0] | |
def analyze_text(txt): | |
""" | |
简单的基于关键词的中文情绪分析 | |
""" | |
if any(w in text for w in ["開心","快樂","愉快","喜悅","歡喜","興奮","歡","高興"]): return "happy" | |
if any(w in text for w in ["生氣","憤怒","不爽","發火","火大","氣憤"]): return "angry" | |
if any(w in text for w in ["傷心","難過","哭","難受","心酸","憂","悲","哀","痛苦","慘","愁"]): return "sad" | |
if any(w in text for w in ["驚訝","意外","嚇","驚詫","詫異","訝異","好奇"]): return "surprise" | |
if any(w in text for w in ["怕","恐懼","緊張","懼","膽怯","畏"]): return "fear" | |
return "neutral" | |
with gr.Blocks(title="多模態即時情緒分析") as demo: | |
gr.Markdown("## 📱 多模態即時情緒分析") | |
tabs = gr.Tabs() | |
with tabs: | |
with gr.TabItem("🔴 Face(即時)"): | |
gr.Markdown("⚠️ Spaces 無法直接打開攝像頭,請本機 `python app.py` 測試;手機/電腦瀏覽器可用以下方式:") | |
camera = gr.Image( | |
source="webcam", | |
type="numpy", | |
label="請對準鏡頭" | |
) | |
face_out = gr.Textbox(label="偵測結果") | |
camera.change(fn=analyze_face, inputs=camera, outputs=face_out) | |
with gr.TabItem("🎤 上傳語音"): | |
wav = gr.File( | |
label="請選擇 .wav 音檔", | |
file_types=["wav"] | |
) | |
audio_out = gr.Textbox(label="偵測結果") | |
wav.upload(fn=analyze_audio, inputs=wav, outputs=audio_out) | |
with gr.TabItem("⌨️ 文本輸入"): | |
txt = gr.Textbox( | |
label="在此輸入文字", | |
placeholder="輸入想要分析的句子…" | |
) | |
text_btn = gr.Button("開始分析") | |
text_out = gr.Textbox(label="偵測結果") | |
text_btn.click(fn=analyze_text, inputs=txt, outputs=text_out) | |
demo.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=False | |
) | |