news 2026/6/13 16:34:02

手把手教你用Python快速统计CASIA/Replay等活体检测数据集信息

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教你用Python快速统计CASIA/Replay等活体检测数据集信息

用Python自动化统计活体检测数据集信息的完整指南

面对CASIA、Replay等活体检测数据集时,手动统计视频文件数量、真假样本比例等信息既耗时又容易出错。本文将教你如何用Python编写自动化脚本,快速生成精确的数据集统计报告。

1. 准备工作与环境配置

在开始编写统计脚本前,我们需要确保开发环境配置正确。推荐使用Python 3.8+版本,这是目前大多数深度学习框架兼容性最好的版本。

首先安装必要的依赖库:

pip install pandas tqdm
  • pandas:用于数据分析和生成结构化统计报告
  • tqdm:为循环操作添加进度条,提升用户体验

建议创建一个专门的Python虚拟环境来管理这些依赖:

python -m venv dataset_stats source dataset_stats/bin/activate # Linux/Mac # 或 dataset_stats\Scripts\activate # Windows

2. 理解数据集目录结构与命名规则

不同活体检测数据集的组织方式各不相同,准确理解其目录结构和命名规则是编写统计脚本的前提。

2.1 CASIA数据集结构分析

CASIA数据集通常按以下方式组织:

CASIA/ ├── train/ │ ├── subject_01/ │ │ ├── 1.avi │ │ ├── 2.avi │ │ ├── HR_1.avi │ │ ├── attack_01.avi │ │ └── ... │ └── ... └── test/ ├── subject_31/ │ ├── 1.avi │ ├── 2.avi │ ├── HR_1.avi │ ├── attack_01.avi │ └── ... └── ...

关键特征:

  • 每个subject包含12个视频
  • 真实样本视频前缀为12HR_1
  • 其余均为攻击样本

2.2 Replay数据集结构分析

Replay数据集的组织更为复杂:

Replay/ ├── train/ │ ├── real/ │ │ ├── client001_session01_controlled.avi │ │ └── ... │ └── attack/ │ ├── print_client001_session01_controlled.avi │ └── ... ├── devel/ # 同train结构 └── test/ # 同train结构

特征:

  • 明确分为real和attack子目录
  • 文件名中包含client和session信息

3. 编写核心统计脚本

基于上述分析,我们可以编写一个通用脚本框架,然后针对不同数据集进行适配。

3.1 基础统计函数

import os from collections import defaultdict import pandas as pd from tqdm import tqdm def count_videos(dataset_path): """基础统计函数""" stats = { 'total': 0, 'real': 0, 'attack': 0, 'subjects': defaultdict(int) } for root, _, files in os.walk(dataset_path): for file in files: if file.endswith('.avi') or file.endswith('.mp4'): stats['total'] += 1 subject_id = os.path.basename(root) stats['subjects'][subject_id] += 1 # 根据文件名判断真实/攻击样本 if is_real_sample(file): stats['real'] += 1 else: stats['attack'] += 1 return stats

3.2 数据集特定适配器

针对CASIA数据集:

def is_real_sample(filename): """CASIA数据集真实样本判断""" return filename.startswith(('1', '2', 'HR_1')) def analyze_casia(dataset_path): stats = count_videos(dataset_path) # 计算训练集/测试集划分 train_subjects = [f"subject_{i:02d}" for i in range(1, 21)] test_subjects = [f"subject_{i:02d}" for i in range(21, 51)] train_stats = { 'videos': sum(stats['subjects'][s] for s in train_subjects), 'real': 0, 'attack': 0 } # 更精确的统计实现... return { 'total': stats['total'], 'train': train_stats, 'test': test_stats }

针对Replay数据集:

def analyze_replay(dataset_path): """Replay数据集专用分析函数""" stats = { 'train': {'real': 0, 'attack': 0}, 'devel': {'real': 0, 'attack': 0}, 'test': {'real': 0, 'attack': 0} } for split in ['train', 'devel', 'test']: split_path = os.path.join(dataset_path, split) real_path = os.path.join(split_path, 'real') attack_path = os.path.join(split_path, 'attack') # 统计真实样本 for root, _, files in os.walk(real_path): stats[split]['real'] += len([f for f in files if f.endswith('.avi')]) # 统计攻击样本 for root, _, files in os.walk(attack_path): stats[split]['attack'] += len([f for f in files if f.endswith('.avi')]) return stats

4. 生成可视化统计报告

收集到原始统计数据后,我们可以使用pandas生成更专业的报告。

4.1 创建DataFrame

def create_stats_dataframe(stats, dataset_name): """将统计结果转换为DataFrame""" data = [] if dataset_name == 'CASIA': data.append({ 'Dataset': dataset_name, 'Split': 'Train', 'Real Videos': stats['train']['real'], 'Attack Videos': stats['train']['attack'], 'Total': stats['train']['videos'] }) # 添加测试集数据... elif dataset_name == 'Replay': for split in ['train', 'devel', 'test']: data.append({ 'Dataset': dataset_name, 'Split': split.capitalize(), 'Real Videos': stats[split]['real'], 'Attack Videos': stats[split]['attack'], 'Total': stats[split]['real'] + stats[split]['attack'] }) return pd.DataFrame(data)

4.2 输出格式化报告

def generate_report(stats_df): """生成格式化的统计报告""" report = [] # 总体统计 total_real = stats_df['Real Videos'].sum() total_attack = stats_df['Attack Videos'].sum() report.append(f"## 数据集总体统计\n") report.append(f"- 总视频数: {total_real + total_attack}") report.append(f"- 真实样本比例: {total_real/(total_real+total_attack):.1%}") report.append(f"- 攻击样本比例: {total_attack/(total_real+total_attack):.1%}\n") # 按划分统计 report.append("## 按数据集划分统计") for _, row in stats_df.iterrows(): report.append( f"### {row['Split']}集\n" f"- 视频总数: {row['Total']}\n" f"- 真实样本: {row['Real Videos']} ({row['Real Videos']/row['Total']:.1%})\n" f"- 攻击样本: {row['Attack Videos']} ({row['Attack Videos']/row['Total']:.1%})" ) return "\n".join(report)

5. 完整工作流集成

将上述组件整合成一个完整的脚本:

def main(): import argparse parser = argparse.ArgumentParser() parser.add_argument('dataset_path', help='Path to dataset directory') parser.add_argument('--dataset-type', choices=['casia', 'replay', 'oulu', 'msu'], required=True, help='Type of dataset to analyze') args = parser.parse_args() if args.dataset_type == 'casia': stats = analyze_casia(args.dataset_path) df = create_stats_dataframe(stats, 'CASIA') elif args.dataset_type == 'replay': stats = analyze_replay(args.dataset_path) df = create_stats_dataframe(stats, 'Replay') # 其他数据集适配... report = generate_report(df) print(report) # 可选:保存���文件 with open('dataset_report.md', 'w') as f: f.write(report) if __name__ == '__main__': main()

使用方式:

python dataset_stats.py /path/to/casia --dataset-type casia

6. 高级功能扩展

6.1 支持多数据集批量处理

def batch_analyze(datasets): """批量分析多个数据集""" all_stats = [] for name, path, dtype in tqdm(datasets, desc="Processing datasets"): try: if dtype == 'casia': stats = analyze_casia(path) df = create_stats_dataframe(stats, name) elif dtype == 'replay': stats = analyze_replay(path) df = create_stats_dataframe(stats, name) # 其他类型... all_stats.append(df) except Exception as e: print(f"Error processing {name}: {str(e)}") return pd.concat(all_stats)

6.2 生成可视化图表

虽然本文不使用mermaid图表,但我们可以用文本表格增强可读性:

| 数据集 | 划分 | 真实样本 | 攻击样本 | 总计 | |---------|-------|---------|---------|-------| | CASIA | Train | 60 | 180 | 240 | | CASIA | Test | 90 | 270 | 360 | | Replay | Train | 60 | 300 | 360 | | Replay | Devel | 60 | 300 | 360 | | Replay | Test | 80 | 400 | 480 |

6.3 异常检测与数据校验

def validate_dataset(stats, expected_counts): """验证数据集完整性""" errors = [] for split in expected_counts: if stats[split]['real'] != expected_counts[split]['real']: errors.append( f"{split}集真实样本数量异常: " f"期望{expected_counts[split]['real']}, 实际{stats[split]['real']}" ) # 其他验证... if errors: raise ValueError("数据集验证失败:\n" + "\n".join(errors))

在实际项目中,我发现这种自动化统计脚本不仅能节省大量时间,还能避免人工统计中的疏漏。特别是在处理像OULU-NPU这样包含近5000个视频的大规模数据集时,手动统计几乎是不可能的任务。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 16:42:42

驱动学习2--WM8960(TODO)

基于现有 Linux 内核中成熟的声卡驱动来学习,是掌握 Linux 音频架构(尤其是 ALSA ASoC 框架)最扎实、最地道的方式。通过阅读和调试经典的驱动源码,你可以清晰地看到硬件寄存器配置、DMA 传输、时钟同步以及音频路由(D…

作者头像 李华
网站建设 2026/6/10 0:21:08

计算机小程序毕设实战-基于Java+SpringBoot+Vue医疗器械管理系统基于springboot+微信小程序的医疗器械预定小程序【完整源码+LW+部署说明+演示视频,全bao一条龙等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华
网站建设 2026/6/10 0:22:54

告别MW库,ICC II新手必看:用Library Manager搞定NDM库创建与配置全流程

ICC II库管理实战:从MW到NDM的平滑迁移指南对于刚从ICC转向ICC II的工程师来说,最令人头疼的莫过于库格式的转换。传统MW库突然变成了陌生的NDM格式,工具界面也完全改头换面。本文将带你深入理解NDM库的核心构成,并通过Library Ma…

作者头像 李华
网站建设 2026/6/10 0:22:57

深入ADRV9009接收链路:手把手解读数字滤波器配置与性能优化

深入ADRV9009接收链路:手把手解读数字滤波器配置与性能优化 在无线通信系统的设计中,射频前端芯片的性能往往决定了整个系统的上限。ADRV9009作为一款高度集成的射频收发器,其内部复杂的数字信号处理链路为工程师提供了极大的灵活性&#xff…

作者头像 李华