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

如何在同一图表中为同帧多面孔绘制不同颜色的情感变化折线图?

解决方案

要实现单帧多人脸的分折线绘制,核心是给每张人脸分配唯一标识,再按标识分组绘制。以下是具体步骤和代码:

1. 给人脸添加唯一ID

如果你的人脸识别系统没有输出跟踪ID,可通过人脸框(bbox)的IOU匹配生成跨帧的统一ID(确保同一人脸在不同帧用同一个ID):

# 先按帧排序数据
df = df.sort_values('Frame').reset_index(drop=True)

# 初始化FaceID列
df['FaceID'] = -1
current_id = 0
prev_faces = {}  # 存储上一帧的人脸框与对应ID

for frame in df['Frame'].unique():
    current_frame = df[df['Frame'] == frame].copy()
    
    if frame == df['Frame'].min():
        # 第一帧直接分配ID
        current_frame['FaceID'] = range(current_id, current_id + len(current_frame))
        current_id += len(current_frame)
        # 记录第一帧的人脸框
        for idx, row in current_frame.iterrows():
            prev_faces[row['FaceID']] = (row['x1'], row['y1'], row['x2'], row['y2'])
    else:
        current_faces = []
        for idx, row in current_frame.iterrows():
            bbox = (row['x1'], row['y1'], row['x2'], row['y2'])
            max_iou = 0
            matched_id = -1
            
            # 计算当前人脸与上一帧所有人脸的IOU,匹配同一人脸
            for face_id, prev_bbox in prev_faces.items():
                x1_inter = max(bbox[0], prev_bbox[0])
                y1_inter = max(bbox[1], prev_bbox[1])
                x2_inter = min(bbox[2], prev_bbox[2])
                y2_inter = min(bbox[3], prev_bbox[3])
                
                inter_area = max(0, x2_inter - x1_inter) * max(0, y2_inter - y1_inter)
                bbox_area = (bbox[2] - bbox[0]) * (bbox[3] - bbox[1])
                prev_area = (prev_bbox[2] - prev_bbox[0]) * (prev_bbox[3] - prev_bbox[1])
                iou = inter_area / (bbox_area + prev_area - inter_area)
                
                if iou > max_iou and iou > 0.5:  # 0.5为IOU匹配阈值,可调整
                    max_iou = iou
                    matched_id = face_id
            
            if matched_id != -1:
                current_faces.append(matched_id)
                prev_faces[matched_id] = bbox
            else:
                # 新出现的人脸分配新ID
                current_faces.append(current_id)
                prev_faces[current_id] = bbox
                current_id += 1
        current_frame['FaceID'] = current_faces
    
    # 更新原DataFrame的FaceID
    df.loc[df['Frame'] == frame, 'FaceID'] = current_frame['FaceID']

如果没有人脸框数据,可临时用帧内编号区分(但跨帧同一人脸会被识别为不同ID):

df['FaceID'] = df.groupby('Frame').cumcount()

2. 绘制情绪随帧变化的分人脸折线图

import matplotlib.pyplot as plt

# 定义情绪与数值的映射
emotion_map = {'Angry': 0, 'Fear': 1, 'Happy': 2, 'Neutral': 3, 'Sad': 4}
df['Emotion_Code'] = df['Emotion'].map(emotion_map)

plt.figure(figsize=(20,5))

# 按FaceID分组绘制折线
for face_id, group in df.groupby('FaceID'):
    # 确保按帧顺序排序
    sorted_group = group.sort_values('Frame')
    plt.plot(sorted_group['Frame'], sorted_group['Emotion_Code'], label=f'人脸 {face_id}')

# 设置y轴刻度与标签
plt.gca().set_yticks(list(emotion_map.values()))
plt.gca().set_yticklabels(list(emotion_map.keys()))

plt.title("各人脸情绪随帧变化")
plt.xlabel("帧编号")
plt.ylabel("情绪")
plt.tick_params(labelsize=10)
# 图例放在右侧避免遮挡
plt.legend(title='人脸ID', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()

3. 年龄、性别绘制的类似方法

年龄折线图

plt.figure(figsize=(20,5))
for face_id, group in df.groupby('FaceID'):
    sorted_group = group.sort_values('Frame')
    plt.plot(sorted_group['Frame'], sorted_group['Age'], label=f'人脸 {face_id}')

plt.title("各人脸年龄随帧变化")
plt.xlabel("帧编号")
plt.ylabel("年龄")
plt.tick_params(labelsize=10)
plt.legend(title='人脸ID', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()

性别折线图

gender_map = {'Male': 0, 'Female': 1}
df['Gender_Code'] = df['Gender'].map(gender_map)

plt.figure(figsize=(20,5))
for face_id, group in df.groupby('FaceID'):
    sorted_group = group.sort_values('Frame')
    plt.plot(sorted_group['Frame'], sorted_group['Gender_Code'], label=f'人脸 {face_id}')

plt.gca().set_yticks(list(gender_map.values()))
plt.gca().set_yticklabels(list(gender_map.keys()))
plt.title("各人脸性别随帧变化")
plt.xlabel("帧编号")
plt.ylabel("性别")
plt.tick_params(labelsize=10)
plt.legend(title='人脸ID', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()

内容的提问来源于stack exchange,提问作者Vidarshana Dissanayaka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:25:19