CASME2数据集入门指南:从数据预处理到微表情识别实战

1次阅读
没有评论

共计 3226 个字符,预计需要花费 9 分钟才能阅读完成。

image.webp

微表情识别与 CASME2 数据集简介

微表情是人类在试图隐藏真实情绪时,面部肌肉短暂且难以控制的表情变化,持续时间通常只有 1 /25 到 1 / 5 秒。在心理学研究、安全审讯和临床诊断等领域具有重要价值。CASME2 是当前最权威的微表情数据集之一,包含 26 名受试者的 247 个样本,具有以下特点:

CASME2 数据集入门指南:从数据预处理到微表情识别实战

  • 分辨率统一为 100×100 像素
  • 每个样本标注了起始帧(onset)、高峰帧(apex)和结束帧(offset)
  • 采用面部动作编码系统(FACS)标注了动作单元(AU)
  • 包含 5 种基本情绪类别:高兴、厌恶、惊讶、压抑和紧张

数据处理中的三大痛点

在实际使用 CASME2 时,初学者常会遇到以下问题:

  1. 视频帧提取困难 :原始 AVI 视频需要逐帧解析,且不同样本的微表情持续时间差异大
  2. 标签解析复杂 :标注信息分散在 Excel 文件和视频元数据中,需要合并处理
  3. 样本不均衡 :各类别样本量差异显著(如紧张类样本占比超过 40%)

技术实现方案

视频帧提取与面部 ROI 处理

使用 OpenCV 进行视频抽帧和面部裁剪:

import cv2

def extract_frames(video_path, output_dir):
    cap = cv2.VideoCapture(video_path)
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

    frame_count = 0
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break

        # 转换为灰度图并检测人脸
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, 1.1, 4)

        for (x,y,w,h) in faces:
            roi = frame[y:y+h, x:x+w]
            resized = cv2.resize(roi, (100, 100))
            cv2.imwrite(f'{output_dir}/frame_{frame_count}.jpg', resized)

        frame_count += 1
    cap.release()

标签文件解析

使用 Pandas 处理 AU_LOGGING.xlsx 文件:

import pandas as pd

def parse_annotations(excel_path):
    df = pd.read_excel(excel_path)
    # 提取关键列并重命名
    annotations = df[['Subject', 'Filename', 'OnsetFrame', 'ApexFrame', 
                      'OffsetFrame', 'Emotion']].copy()
    annotations.columns = ['subject', 'filename', 'onset', 'apex', 'offset', 'emotion']

    # 处理情绪类别编码
    emotion_map = {'happiness':0, 'disgust':1, 'surprise':2, 
                  'repression':3, 'tension':4}
    annotations['label'] = annotations['emotion'].map(emotion_map)

    return annotations

处理类别不平衡

在 PyTorch 中使用加权随机采样:

from torch.utils.data import WeightedRandomSampler

# 计算每个类别的样本权重
class_counts = np.bincount(labels)
class_weights = 1. / class_counts
sample_weights = class_weights[labels]

sampler = WeightedRandomSampler(
    weights=sample_weights,
    num_samples=len(sample_weights),
    replacement=True
)

dataloader = DataLoader(dataset, batch_size=32, sampler=sampler)

模型架构设计

3D-CNN 与传统 2D-CNN 对比

特性 2D-CNN 3D-CNN
输入维度 (C, H, W) (C, T, H, W)
卷积方式 空间卷积 时空卷积
时序建模 需额外 LSTM 原生支持
参数量 较少 较大
适用场景 静态特征提取 动态序列分析

P3D-ResNet 轻量级实现

基于 PyTorch 的模型核心结构:

import torch.nn as nn

class P3DBlock(nn.Module):
    def __init__(self, in_channels, out_channels):
        super().__init__()
        # 空间卷积分支
        self.spatial = nn.Sequential(nn.Conv3d(in_channels, out_channels, kernel_size=(1,3,3), padding=(0,1,1)),
            nn.BatchNorm3d(out_channels),
            nn.ReLU())
        # 时序卷积分支
        self.temporal = nn.Sequential(nn.Conv3d(out_channels, out_channels, kernel_size=(3,1,1), padding=(1,0,0)),
            nn.BatchNorm3d(out_channels),
            nn.ReLU())

    def forward(self, x):
        x = self.spatial(x)
        x = self.temporal(x)
        return x

class MicroExpressionNet(nn.Module):
    def __init__(self, num_classes=5):
        super().__init__()
        self.features = nn.Sequential(P3DBlock(3, 64),
            nn.MaxPool3d(kernel_size=(1,2,2)),
            P3DBlock(64, 128),
            nn.MaxPool3d(kernel_size=(1,2,2)),
            P3DBlock(128, 256)
        )
        self.classifier = nn.Sequential(nn.AdaptiveAvgPool3d(1),
            nn.Flatten(),
            nn.Linear(256, num_classes)
        )

    def forward(self, x):
        # x 形状: (B, C, T, H, W)
        x = self.features(x)
        return self.classifier(x)

训练技巧与避坑指南

关键训练配置

  1. 学习率调度 :初始学习率设为 3e-4,每 10 个 epoch 衰减 0.1 倍
  2. 梯度累积 :在小批量显存不足时使用(示例配置 accum_steps=4)
  3. 早停机制 :当验证集损失连续 5 个 epoch 不下降时终止训练

常见问题解决方案

  • 面部对齐问题 :
  • 使用 dlib 的 68 点特征检测替代 OpenCV Haar 特征
  • 对裁剪区域增加 10% 的边界缓冲

  • 过拟合对策 :

  • 在 P3D 块后添加 Dropout 层(p=0.3)
  • 使用 MixUp 数据增强(α=0.2)
  • 限制训练 epoch 不超过 50

性能评估与结果

在 80%-20% 的训练 - 验证划分下,模型应达到:

指标 目标值
加权准确率 ≥0.68
加权 F1-score ≥0.65
各类别召回率 ≥0.55

开放性问题思考

对于极低强度微表情的检测,可以考虑:
1. 引入光流特征作为补充输入
2. 使用注意力机制强化关键帧特征
3. 设计专用的微表情强度评估模块
4. 结合心理学先验知识约束模型

结语

通过本实践,我们完成了从原始 CASME2 数据到可运行微表情识别系统的完整流程。建议初学者先复现基线模型,再逐步尝试:调整网络深度、引入 Transformer 模块、测试不同的数据增强策略等改进方向。记住在微表情识别任务中,时序建模能力和细粒度特征提取同样重要。

正文完
 0
评论(没有评论)