You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将面部情绪检测模型识别的情绪保存至DataFrame或Excel?

实现面部情绪检测数据保存到DataFrame/Excel的方案

步骤说明

  1. 安装依赖库:需要pandas处理DataFrame,openpyxl用于写入Excel文件。执行以下命令安装:
pip install pandas openpyxl
  1. 导入必要模块:在原有代码基础上添加pandas和datetime模块,用于数据存储和时间戳记录。

  2. 初始化数据存储结构:创建一个列表来临时存储每条情绪记录,避免循环中频繁修改DataFrame影响性能。

  3. 捕获并记录情绪数据:在情绪判断的分支中,将检测到的情绪、时间戳及关键 landmark 距离存入列表。

  4. 保存数据到Excel:程序退出时,将列表转换为DataFrame并写入Excel文件。

修改后的完整代码

import cv2
import mediapipe as mp
import math
import pandas as pd
from datetime import datetime

cap = cv2.VideoCapture(0)
cap.set(3, 1280)
cap.set(4, 720)

mpDibujo = mp.solutions.drawing_utils
ConfDibu = mpDibujo.DrawingSpec(thickness=1, circle_radius=1)
mpMallaFacial = mp.solutions.face_mesh
MallaFacial = mpMallaFacial.FaceMesh(max_num_faces=1)

# 初始化情绪记录列表
emotion_records = []

while True:
    ret, frame = cap.read()
    frameRGB = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    resultados = MallaFacial.process(frameRGB)
    px = []
    py = []
    lista = []
    r = 5
    t = 3
    detected_emotion = None  # 初始化当前帧检测到的情绪

    if resultados.multi_face_landmarks:
        for rostros in resultados.multi_face_landmarks:
            mpDibujo.draw_landmarks(frame, rostros, mpMallaFacial.FACEMESH_TESSELATION, ConfDibu, ConfDibu)
            for id, puntos in enumerate(rostros.landmark):
                al, an, c = frame.shape
                x, y = int(puntos.x * an), int(puntos.y * al)
                px.append(x)
                px.append(y)
                lista.append([id, x, y])
                
                if len(lista) == 468:
                    x1, y1 = lista[65][1:]
                    x2, y2 = lista[158][1:]
                    longitud1 = math.hypot(x2 - x1, y2 - y1)
                    
                    x3, y3 = lista[295][1:]
                    x4, y4 = lista[385][1:]
                    longitud2 = math.hypot(x4 - x3, y4 - y3)
                    
                    x5, y5 = lista[78][1:]
                    x6, y6 = lista[308][1:]
                    longitud3 = math.hypot(x6 - x5, y6 - y5)
                    
                    x7, y7 = lista[13][1:]
                    x8, y8 = lista[14][1:]
                    longitud4 = math.hypot(x8 - x7, y8 - y7)

                    # 判断情绪并记录
                    if longitud1 < 19 and longitud2 < 19 and longitud3 > 80 and longitud3 < 95 and longitud4 < 5:
                        cv2.putText(frame, 'Persona enojada', (480,80), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
                        detected_emotion = 'Enojada'
                    elif longitud1 > 20 and longitud1 < 30 and longitud2 > 20 and longitud2 < 30 and longitud3 > 109 and longitud4 > 10 and longitud4 < 20:
                        cv2.putText(frame, 'Persona feliz', (480,80), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 3)
                        detected_emotion = 'Feliz'
                    elif longitud1 > 35 and longitud2 > 35 and longitud3 > 80 and longitud3 < 90 and longitud4 > 20:
                        cv2.putText(frame, 'Persona asombrada', (480,80), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3)
                        detected_emotion = 'Asombrada'
                    elif longitud1 > 20 and longitud1 < 35 and longitud2 > 20 and longitud2 < 35 and longitud3 > 90 and longitud3 < 95 and longitud4 < 5:
                        cv2.putText(frame, 'Persona triste', (480,80), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 3)
                        detected_emotion = 'Triste'

                    # 如果检测到情绪,添加到记录列表
                    if detected_emotion:
                        emotion_records.append({
                            'Timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],  # 保留毫秒
                            'Emocion': detected_emotion,
                            'Longitud1': round(longitud1, 2),
                            'Longitud2': round(longitud2, 2),
                            'Longitud3': round(longitud3, 2),
                            'Longitud4': round(longitud4, 2)
                        })

    cv2.imshow("Reconocimiento de emociones", frame)
    t = cv2.waitKey(1)
    if t == 27:
        break

cap.release()
cv2.destroyAllWindows()

# 将记录转换为DataFrame并保存到Excel
if emotion_records:
    df = pd.DataFrame(emotion_records)
    df.to_excel('registro_emociones.xlsx', index=False, engine='openpyxl')
    print(f"数据已保存到 registro_emociones.xlsx,共 {len(df)} 条记录")
else:
    print("未检测到任何情绪记录")

关键说明

  • 时间戳:精确到毫秒,方便分析情绪变化的时序性。
  • Landmark距离:保存判断情绪的关键参数,便于后续优化情绪识别阈值。
  • 性能优化:使用列表临时存储记录,最后一次性转换为DataFrame,避免循环中频繁操作DataFrame导致的性能下降。
  • Excel保存:使用openpyxl引擎确保xlsx格式的兼容性,index=False避免生成多余的索引列。

内容的提问来源于stack exchange,提问作者Matthew Renteria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 11:55:25