IMX6U_SYS/SYSTEM_IMPLEMENTATION_PLAN.md

498 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 课前拍照打卡系统实现规划
## 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. 添加人工复核功能,修正误识别和漏识别结果。