本项目用于构建基于单帧正脸图像的笑容状态分类数据集,包含从视频中抽取数据、人工标注、以及后续数据筛选与采样的完整流程。
目标任务为单帧三分类:
true_smilenot_smileother_smile
项目整体以单帧视角为核心,不依赖 segment 作为训练输入结构,但在数据准备阶段会利用笑容片段(segment)信息进行筛选。
- 输入数据来自连续视频
- 视频中并非所有时间段都包含笑容
- 已通过 FaceTracking 提取出:
- 仅包含正脸的单帧图像(224×224)
- 同时,人工或半自动方式标注了笑容片段区间(
segment.dat)
因此,数据准备阶段包含两类核心数据:
- 单帧正脸图像文件夹
- 对应视频中的笑容片段区间定义文件(
segment.dat)
- 在网页中点击“选择文件夹”
- 浏览器读取该文件夹下的所有图片文件
- 页面一次只显示一张图片(当前索引
i)
说明
由于浏览器安全限制,纯前端 HTML 无法直接访问系统真实路径。
通常使用:
<input type="file" webkitdirectory>浏览器会提供:
File对象webkitRelativePath(相对路径)
导出标注结果时,使用该相对路径作为“目录 + 文件名”的表示。
固定三类标签:
true_smilenot_smileother_smile
交互方式:
| 操作方式 | 行为 |
|---|---|
| 鼠标点击 | 对应标签按钮 |
q |
true_smile |
p |
not_smile |
Space |
other_smile |
Backspace |
返回上一张图片 |
- 完成当前图片标注后,自动跳转下一张
- 返回上一张时,可修改已有标注
-
为每张图片维护一个
path -> label的映射 -
当切换图片时:
- 若该图片已被标注
- 页面会显示当前已有的 label 状态
点击 Export .dat 时,流程如下:
- 将所有标注结果拼接为一段纯文本
- 使用
Blob在浏览器内存中生成临时文件 - 触发浏览器下载行为
本质上与下载 PDF / ZIP 文件一致。
导出格式:
relative_path label
Press D → discard current image (removed from the annotation queue, not exported)
A Discard button
UI stats updated to show Loaded / Remaining / Labeled / Discarded
Hint text updated to include D
基于区间的单帧人脸图像抽取脚本
从 FaceTracking 输出的单帧正脸图像目录中,根据记录笑容片段区间的 .dat 文件,批量抽取(移动或复制)区间内对应帧号的所有图像,并汇总到新的目标文件夹中。
- 以单帧视角工作
- 不使用 segment 作为训练结构
- 仅在数据筛选阶段利用区间信息
-
源图像文件夹(SRC_DIR)
-
FaceTracking 输出的正脸图像
-
文件名格式:
<PREFIX><frame_number><EXT> -
示例:
20250926_0_0_155.png
-
-
区间定义文件(DAT_PATH)
- 文本格式
- 每行表示一个区间
- 仅解析前两列(起始帧号、结束帧号)
示例:
# start_frame end_frame label remark 155 299 false_smile 783 863 false_smile 5264 5377 false_smile
-
一个新的目标文件夹(
DST_DIR),包含:- 所有区间内且实际存在的帧图像
- 可选生成
missing_frames.txt,记录区间内缺失的帧(例如因非正脸被 FaceTracking 过滤)
-
区间解析与去重
- 展开所有
[start_frame, end_frame] - 合并为唯一帧号集合
- 即使区间重叠,同一帧只处理一次
- 展开所有
-
自动容错
- 缺失帧自动跳过
- 不中断执行
- 可记录到
missing_frames.txt
-
文件操作模式
-
支持
move / copy -
支持:
- Dry-run
- 是否覆盖已有文件
-
多目录随机抽样单帧图像脚本
从任意数量的图像文件夹中汇总所有单帧图像,并随机抽取指定数量的样本,统一输出到一个新的文件夹中。
主要用于:
- 构建预标注数据集
- 构建正式数据集前的随机子集
- 在不引入时间 / segment 结构的情况下进行单帧采样
-
源目录列表(SOURCE_DIRS)
- 支持任意数量目录
- 每个目录包含 FaceTracking 输出的正脸单帧图像
- 可配置是否递归遍历
-
采样数量(SAMPLE_N)
- 如:
1000用于预标注 - 后续可调整为更大数值
- 如:
-
一个输出目录(
OUTPUT_DIR),包含:- 随机抽取的
SAMPLE_N张图像 - 若发生文件名冲突,自动追加后缀(
__2,__3, …)
- 随机抽取的
-
多目录汇总
-
自动收集所有符合扩展名的图像
-
支持:
.png / .jpg / .jpeg / .bmp / .webp
-
-
随机抽样
- 使用
random.sample(无放回) - 支持固定随机种子(可复现)
- 当采样数大于可用样本数时直接报错
- 使用
-
文件输出控制
- 支持 copy / move
- 是否覆盖已有文件可配置
- Dry-run 模式支持
-
单帧视角优先
-
segment 仅用于数据筛选,不作为模型输入结构
-
所有工具均支持:
- 可回滚
- 可复现
- 可扩展
该流程适用于后续:
- 单帧笑容分类实验
- 预标注 / 正式标注阶段切换
- 不同采样策略的对比实验
12-22 我想要分别一张图是真笑和假笑。 但是我发现有很多的照片我是没有办法分辨的。 所以针对这个,我在想。 先识别出这个人在笑再说。
12-23: 我标注的图片的来源是我之前的笑容片段。 我发现,即使数据源是笑容片段,还是有非常多的单帧数据被我标注为没有在笑。 不同人其实对同一张图片的认知其实是不同的 所以在打标的时候,是不是用投票机制会好一点? 我自己用了voting
增加了voting脚本
不要在全量数据上先删再切分。正确做法是:
先切分
只对 train 做下采样/增强
val/test 保持原分布(否则评估失真)
所以是数据清洗之后拆分,然后做下采样和增强
0 448条 1 254条
路径需要对齐
cd E:\Single_frame_smile python -m venv .venv ..venv\Scripts\activate python -m pip install --upgrade pip