commit 8a69fa01c98697ccf498ca72cbc5302a5f91c557 Author: HP <2726519488@qq.com> Date: Thu Jun 4 19:32:20 2026 +0800 Initial commit: project setup with CMake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5cfa19c --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ +# Build directories +build/ +build-*/ +cmake-build-*/ +out/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# CMake +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake +Makefile +compile_commands.json +CTestTestfile.cmake + +# Compiled binaries +*.exe +*.out +*.app +*.dll +*.so +*.a +*.lib + +# OS files +.DS_Store +Thumbs.db + +# Runtime data (large files / generated content) +data/faces/* +data/images/* +data/results/* +data/database/* +!data/*/.gitkeep + +# Models (large binary files, if needed use Git LFS) +models/*/* +!models/*/.gitkeep diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/SYSTEM_IMPLEMENTATION_PLAN.md b/SYSTEM_IMPLEMENTATION_PLAN.md new file mode 100644 index 0000000..6d1a339 --- /dev/null +++ b/SYSTEM_IMPLEMENTATION_PLAN.md @@ -0,0 +1,497 @@ +# 课前拍照打卡系统实现规划 + +## 1. 系统目标 + +本系统基于 IMX6ULL_ALPHA 板端单机运行,优先拆分为两个相对独立的功能: + +1. 大图人头数统计功能:对一张课堂大图进行检测,统计图片中出现的人数或人头数。 +2. 单张人脸匹配功能:对单个清晰人脸进行识别匹配,判断该人脸是否属于已注册人员。 + +当前阶段不直接实现“课堂大图中所有人脸逐一识别”的完整流程,而是先完成两个基础能力: + +- 证明板端能够完成轻量目标检测。 +- 证明板端能够完成单人脸特征提取和数据库匹配。 +- 为后续合并成完整课前拍照打卡流程做准备。 + +## 2. 技术路线 + +### 2.1 推荐技术栈 + +- 操作系统:Linux,运行在 IMX6ULL_ALPHA 开发板。 +- 图像采集:V4L2 摄像头接口。 +- 图像处理:OpenCV。 +- 模型推理:ncnn 或 TFLite Micro/TFLite。 +- 数据存储:SQLite。 +- 配置文件:JSON 或 INI。 +- 日志:本地文本日志。 + +### 2.2 模型选择建议 + +大图人头数统计可以选择: + +- YOLOv5n/YOLOv8n 的轻量化人头检测模型。 +- YOLO-Fastest 人头检测模型。 +- NanoDet 或其他轻量目标检测模型。 +- 如果只做人脸计数,也可以使用 YuNet 等轻量人脸检测模型。 + +单张人脸匹配可以选择: + +- MobileFaceNet。 +- SFace。 +- 其他轻量 ArcFace 结构模型。 + +模型需要尽量转换为适合 ARM CPU 推理的格式: + +- ncnn:`.param` + `.bin` +- TFLite:`.tflite` + +## 3. 功能拆分 + +## 3.1 大图人头数统计功能 + +### 3.1.1 功能目标 + +输入一张课堂大图,系统检测图中所有人头或人脸位置,输出人数统计结果,并保存检测信息。 + +### 3.1.2 需要实现的功能 + +1. 摄像头拍照 + - 从 USB 摄像头或 DVP 摄像头采集一帧图片。 + - 保存原始图片到本地。 + - 支持从本地图片文件读取,方便调试。 + +2. 图片预处理 + - 调整图片尺寸。 + - 格式转换,如 BGR/RGB。 + - 归一化处理。 + - 根据模型输入要求进行 padding 或 resize。 + +3. 人头检测推理 + - 加载轻量检测模型。 + - 对课堂大图执行推理。 + - 输出候选框、置信度、类别。 + +4. 后处理 + - 解析模型输出。 + - 执行 NMS 去重。 + - 过滤低置信度目标。 + - 统计最终人头数量。 + +5. 结果保存 + - 保存检测框坐标。 + - 保存统计人数。 + - 保存检测时间。 + - 保存带框的结果图片。 + - 将结果写入 SQLite 数据库。 + +6. 结果显示 + - 在终端输出统计结果。 + - 后续可扩展到 LCD 或 Web 页面展示。 + +### 3.1.3 输出结果示例 + +```json +{ + "image_path": "data/images/session_001.jpg", + "result_image_path": "data/results/session_001_detected.jpg", + "head_count": 36, + "detections": [ + { + "x": 120, + "y": 85, + "w": 32, + "h": 36, + "score": 0.91 + } + ], + "created_at": "2026-06-04 09:00:00" +} +``` + +## 3.2 单张人脸匹配功能 + +### 3.2.1 功能目标 + +输入一张单人脸图片,系统提取人脸特征,与本地数据库中的注册人脸特征进行匹配,输出识别结果。 + +### 3.2.2 需要实现的功能 + +1. 人员注册 + - 输入学生姓名、学号、班级等信息。 + - 采集或导入单张人脸图片。 + - 检测图片中的人脸。 + - 裁剪并对齐人脸。 + - 提取人脸特征向量。 + - 保存人员信息和特征向量到 SQLite。 + +2. 单张人脸检测 + - 从图片中检测单个人脸。 + - 如果检测到多张人脸,默认选择最大或最清晰的人脸。 + - 如果未检测到人脸,返回失败信息。 + +3. 人脸对齐 + - 根据眼睛、鼻尖、嘴角等关键点进行对齐。 + - 输出统一尺寸的人脸图,例如 `112x112`。 + +4. 特征提取 + - 加载轻量人脸识别模型。 + - 输出固定长度特征向量。 + - 对特征向量进行归一化。 + +5. 特征匹配 + - 从 SQLite 读取已注册人员特征。 + - 使用余弦相似度或欧氏距离进行比较。 + - 找到最高分人员。 + - 根据阈值判断是否识别成功。 + +6. 识别记录保存 + - 保存识别图片路径。 + - 保存匹配到的学生 ID。 + - 保存相似度分数。 + - 保存识别状态。 + - 保存识别时间。 + +### 3.2.3 输出结果示例 + +```json +{ + "input_image": "data/images/face_test_001.jpg", + "matched": true, + "student_id": "20240001", + "name": "张三", + "score": 0.82, + "threshold": 0.75, + "created_at": "2026-06-04 09:05:00" +} +``` + +## 4. 建议目录结构 + +```text +attendance-system/ +├── README.md +├── SYSTEM_IMPLEMENTATION_PLAN.md +├── CMakeLists.txt +├── config/ +│ ├── app_config.json +│ ├── camera_config.json +│ └── model_config.json +├── models/ +│ ├── head_detect/ +│ │ ├── head_detect.param +│ │ └── head_detect.bin +│ └── face_recognition/ +│ ├── face_detect.param +│ ├── face_detect.bin +│ ├── face_feature.param +│ └── face_feature.bin +├── data/ +│ ├── images/ +│ ├── faces/ +│ ├── results/ +│ └── database/ +│ └── attendance.db +├── include/ +│ ├── app/ +│ │ ├── app_context.h +│ │ └── app_config.h +│ ├── camera/ +│ │ └── camera_capture.h +│ ├── common/ +│ │ ├── image_utils.h +│ │ ├── logger.h +│ │ └── time_utils.h +│ ├── database/ +│ │ ├── attendance_db.h +│ │ └── face_repository.h +│ ├── head_count/ +│ │ ├── head_counter.h +│ │ ├── head_detector.h +│ │ └── detect_postprocess.h +│ └── face_match/ +│ ├── face_detector.h +│ ├── face_aligner.h +│ ├── face_feature_extractor.h +│ └── face_matcher.h +├── src/ +│ ├── main.cpp +│ ├── app/ +│ │ ├── app_context.cpp +│ │ └── app_config.cpp +│ ├── camera/ +│ │ └── camera_capture.cpp +│ ├── common/ +│ │ ├── image_utils.cpp +│ │ ├── logger.cpp +│ │ └── time_utils.cpp +│ ├── database/ +│ │ ├── attendance_db.cpp +│ │ └── face_repository.cpp +│ ├── head_count/ +│ │ ├── head_counter.cpp +│ │ ├── head_detector.cpp +│ │ └── detect_postprocess.cpp +│ └── face_match/ +│ ├── face_detector.cpp +│ ├── face_aligner.cpp +│ ├── face_feature_extractor.cpp +│ └── face_matcher.cpp +├── tools/ +│ ├── register_face.cpp +│ ├── test_head_count.cpp +│ ├── test_face_match.cpp +│ └── init_database.cpp +├── scripts/ +│ ├── build_arm.sh +│ ├── build_pc.sh +│ └── convert_model.md +├── tests/ +│ ├── test_head_postprocess.cpp +│ └── test_face_similarity.cpp +└── docs/ + ├── database_design.md + ├── model_deployment.md + └── board_deployment.md +``` + +## 5. 主要文件功能说明 + +### 5.1 根目录文件 + +| 文件 | 功能 | +| --- | --- | +| `README.md` | 项目说明、编译方式、运行方式 | +| `SYSTEM_IMPLEMENTATION_PLAN.md` | 当前系统实现规划 | +| `CMakeLists.txt` | C++ 工程编译配置 | + +### 5.2 配置目录 + +| 文件 | 功能 | +| --- | --- | +| `config/app_config.json` | 系统运行参数,如日志级别、数据目录、是否保存结果图 | +| `config/camera_config.json` | 摄像头设备号、分辨率、帧率、图片格式 | +| `config/model_config.json` | 模型路径、输入尺寸、置信度阈值、匹配阈值 | + +### 5.3 模型目录 + +| 文件或目录 | 功能 | +| --- | --- | +| `models/head_detect/` | 大图人头检测模型 | +| `models/face_recognition/face_detect.*` | 单张人脸检测模型 | +| `models/face_recognition/face_feature.*` | 人脸特征提取模型 | + +### 5.4 数据目录 + +| 目录或文件 | 功能 | +| --- | --- | +| `data/images/` | 原始拍照图片和测试图片 | +| `data/faces/` | 注册时裁剪后的人脸图片 | +| `data/results/` | 检测后带框图片、识别结果图片 | +| `data/database/attendance.db` | SQLite 数据库文件 | + +### 5.5 摄像头模块 + +| 文件 | 功能 | +| --- | --- | +| `include/camera/camera_capture.h` | 摄像头采集接口定义 | +| `src/camera/camera_capture.cpp` | V4L2 或 OpenCV 摄像头采集实现 | + +### 5.6 大图人头数统计模块 + +| 文件 | 功能 | +| --- | --- | +| `include/head_count/head_detector.h` | 人头检测模型接口定义 | +| `src/head_count/head_detector.cpp` | 加载模型并执行人头检测 | +| `include/head_count/detect_postprocess.h` | 检测后处理接口定义 | +| `src/head_count/detect_postprocess.cpp` | 解码模型输出、NMS、置信度过滤 | +| `include/head_count/head_counter.h` | 人头统计主流程接口 | +| `src/head_count/head_counter.cpp` | 调用预处理、检测、后处理并输出人数 | + +### 5.7 单张人脸匹配模块 + +| 文件 | 功能 | +| --- | --- | +| `include/face_match/face_detector.h` | 人脸检测接口定义 | +| `src/face_match/face_detector.cpp` | 检测输入图片中的人脸 | +| `include/face_match/face_aligner.h` | 人脸对齐接口定义 | +| `src/face_match/face_aligner.cpp` | 根据关键点裁剪并对齐人脸 | +| `include/face_match/face_feature_extractor.h` | 人脸特征提取接口定义 | +| `src/face_match/face_feature_extractor.cpp` | 调用模型生成人脸特征向量 | +| `include/face_match/face_matcher.h` | 人脸匹配接口定义 | +| `src/face_match/face_matcher.cpp` | 计算相似度并返回最佳匹配人员 | + +### 5.8 数据库模块 + +| 文件 | 功能 | +| --- | --- | +| `include/database/attendance_db.h` | 数据库初始化、连接、通用操作接口 | +| `src/database/attendance_db.cpp` | SQLite 数据库操作实现 | +| `include/database/face_repository.h` | 人员信息和人脸特征数据访问接口 | +| `src/database/face_repository.cpp` | 注册人员、读取特征、保存识别记录 | + +### 5.9 公共工具模块 + +| 文件 | 功能 | +| --- | --- | +| `include/common/image_utils.h` | 图片读取、保存、缩放、画框等工具函数 | +| `src/common/image_utils.cpp` | 图片工具函数实现 | +| `include/common/logger.h` | 日志接口定义 | +| `src/common/logger.cpp` | 日志输出实现 | +| `include/common/time_utils.h` | 时间格式化接口 | +| `src/common/time_utils.cpp` | 时间工具实现 | + +### 5.10 工具程序 + +| 文件 | 功能 | +| --- | --- | +| `tools/init_database.cpp` | 初始化 SQLite 表结构 | +| `tools/register_face.cpp` | 注册学生人脸信息 | +| `tools/test_head_count.cpp` | 输入大图,测试人头统计功能 | +| `tools/test_face_match.cpp` | 输入单人脸图,测试人脸匹配功能 | + +## 6. 数据库初步设计 + +### 6.1 students 表 + +保存学生基础信息。 + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `id` | INTEGER | 主键 | +| `student_no` | TEXT | 学号 | +| `name` | TEXT | 姓名 | +| `class_name` | TEXT | 班级 | +| `created_at` | TEXT | 创建时间 | + +### 6.2 face_templates 表 + +保存注册人脸特征。 + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `id` | INTEGER | 主键 | +| `student_id` | INTEGER | 对应学生 ID | +| `face_image_path` | TEXT | 注册人脸图片路径 | +| `feature` | BLOB | 人脸特征向量 | +| `feature_dim` | INTEGER | 特征维度 | +| `model_version` | TEXT | 特征模型版本 | +| `created_at` | TEXT | 创建时间 | + +### 6.3 head_count_records 表 + +保存大图人头统计结果。 + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `id` | INTEGER | 主键 | +| `image_path` | TEXT | 原图路径 | +| `result_image_path` | TEXT | 带框结果图路径 | +| `head_count` | INTEGER | 统计人数 | +| `detections_json` | TEXT | 检测框 JSON | +| `created_at` | TEXT | 创建时间 | + +### 6.4 face_match_records 表 + +保存单张人脸识别记录。 + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `id` | INTEGER | 主键 | +| `input_image_path` | TEXT | 输入图片路径 | +| `matched_student_id` | INTEGER | 匹配学生 ID,未匹配时为空 | +| `score` | REAL | 相似度分数 | +| `threshold` | REAL | 使用的匹配阈值 | +| `status` | TEXT | `matched`、`unknown`、`failed` | +| `created_at` | TEXT | 创建时间 | + +## 7. 主程序运行模式 + +主程序可以先设计为命令行方式,方便调试和答辩展示。 + +### 7.1 大图人头统计 + +```bash +./attendance_app --mode head_count --image data/images/classroom.jpg +``` + +输出: + +```text +head count: 36 +result image: data/results/classroom_detected.jpg +``` + +### 7.2 注册人脸 + +```bash +./register_face --student-no 20240001 --name zhangsan --class-name class01 --image data/faces/zhangsan.jpg +``` + +输出: + +```text +register success: 20240001 zhangsan +``` + +### 7.3 单张人脸匹配 + +```bash +./attendance_app --mode face_match --image data/images/test_face.jpg +``` + +输出: + +```text +matched: true +student_no: 20240001 +name: zhangsan +score: 0.82 +``` + +## 8. 实施顺序 + +建议按以下顺序实现: + +1. 搭建 CMake 工程目录。 +2. 实现图片读取、保存、画框等基础工具。 +3. 实现 SQLite 数据库初始化。 +4. 在 PC 上跑通大图人头统计模型。 +5. 在 PC 上跑通单张人脸匹配模型。 +6. 将模型转换为 ncnn 或 TFLite 格式。 +7. 交叉编译 OpenCV、SQLite、ncnn/TFLite 到 IMX6ULL。 +8. 将程序部署到 IMX6ULL_ALPHA 板端。 +9. 测试摄像头拍照。 +10. 测试板端人头统计速度和准确率。 +11. 测试板端单张人脸匹配速度和准确率。 +12. 根据实际性能调整模型大小、输入分辨率和阈值。 + +## 9. 当前阶段验收标准 + +### 9.1 大图人头统计 + +- 能读取一张课堂大图。 +- 能检测出主要人头或人脸位置。 +- 能输出人数统计值。 +- 能保存带检测框的结果图片。 +- 能把统计结果写入 SQLite。 + +### 9.2 单张人脸匹配 + +- 能注册至少 5 名学生的人脸。 +- 能对单张清晰人脸进行匹配。 +- 能输出姓名、学号、相似度。 +- 能识别未知人员。 +- 能把识别记录写入 SQLite。 + +## 10. 后续扩展方向 + +完成两个基础功能后,可以继续扩展为完整课前拍照打卡系统: + +1. 将大图中的每个人脸裁剪出来。 +2. 对每个人脸分别执行特征提取。 +3. 与数据库中所有学生特征进行匹配。 +4. 对同一学生的多个匹配结果进行去重。 +5. 生成一次课堂考勤记录。 +6. 添加 LCD 显示界面或 Web 管理页面。 +7. 添加人工复核功能,修正误识别和漏识别结果。 + diff --git a/data/database/.gitkeep b/data/database/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/faces/.gitkeep b/data/faces/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/images/.gitkeep b/data/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/data/results/.gitkeep b/data/results/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/models/face_recognition/.gitkeep b/models/face_recognition/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/models/head_detect/.gitkeep b/models/head_detect/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..e69de29