如何将面部情绪检测模型识别的情绪保存至DataFrame或Excel?
实现面部情绪检测数据保存到DataFrame/Excel的方案
步骤说明
- 安装依赖库:需要
pandas处理DataFrame,openpyxl用于写入Excel文件。执行以下命令安装:
pip install pandas openpyxl
导入必要模块:在原有代码基础上添加
pandas和datetime模块,用于数据存储和时间戳记录。初始化数据存储结构:创建一个列表来临时存储每条情绪记录,避免循环中频繁修改DataFrame影响性能。
捕获并记录情绪数据:在情绪判断的分支中,将检测到的情绪、时间戳及关键 landmark 距离存入列表。
保存数据到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
相关产品推荐
相关产品推荐

