
还在为证件照表情僵硬、背景不规范、排队久而烦恼?这套系统让你告别焦虑!
*📂 **源代码地址**:Skeleton_Portrait-collection 🎯 **参赛信息**:第三届3D视觉创新应用竞赛 | 参赛者:方翔*
📌 项目亮点
| 亮点 | 内容 |
|---|---|
| 🤖 全流程自动化 | 身份核验 → 姿态检测 → 自动采集 → AI精修,全链路一条龙 |
| 🎯 姿态识别黑科技 | Yolov5 + AlphaPose + ST-GCN,精准判断"歪头杀"和"低头族" |
| 🔒 身份安全双保险 | 身份证读卡器 vs 人脸比对,冒名顶替?不存在的! |
| ✨ AI美颜不假面 | 告别"蛇精脸",保留自然美感,证件照也能很好看 |
| ☁️ 云端协同管理 | 预约 → 拍照 → 取片,数据流转无缝衔接 |
一、项目背景
1.1 证件照的"世纪难题" 😩
你有没有遇到过这些让人头秃的情况?
- 📸 精心打扮出门,结果拍出来像"通缉令"……
- 😓 排队两小时,拍照三秒钟,还没来得及摆好 pose 就被"咔嚓"了
- 😤 重拍了五六次,姿态总是不合格,心态直接崩掉
- 🧾 换个证件又要重新拍,蓝底白底红底傻傻分不清
据不完全统计,超过 60% 的人对自己证件照不满意,而其中绝大多数问题都出在 拍摄姿势不规范 和 后期处理不到位 上。
1.2 市场现状与痛点
| 痛点 | 描述 | 影响 |
|---|---|---|
| ⚠️ 姿态规范难保障 | 完全依赖人工引导或用户自觉 | 不合格照片率高,重复拍摄 |
| 🔓 身份核验缺失 | 无法有效验证持证人与证件一致性 | 存在冒用风险 |
| 🖼️ 后期处理繁琐 | 用户无法参与修图决策 | 满意度低,投诉率高 |
| 📦 数据孤岛严重 | 各系统独立,流程割裂 | 效率低,体验差 |
1.3 我们的解题思路 💡
"与其改变用户,不如用 AI 去'看懂'用户。"
本项目打造了一套 软硬件协同的智能人像采集系统,通过深度学习算法自动引导用户摆出标准姿势,结合 Femto 3D 相机精准采集人像数据,再由 AI 辅助完成高质量证件照处理——最终实现 "一次拍好,终身受益" 的美好愿景 🌟
二、系统整体架构
2.1 架构概览
系统由 四大核心模块 和 两大硬件设备 组成:

2.2 硬件选型
| 设备 | 型号 | 作用 |
|---|---|---|
| 📷 3D深度相机 | Orbbec Femto | 采集高质量 RGB-D 人像数据 |
| 🪪 身份证读卡器 | 华视100UC | 读取身份证芯片信息,进行身份核验 |
2.3 软件技术栈
| 层级 | 技术选型 |
|---|---|
| 前端界面 | Qt / WPF(跨平台桌面应用) |
| 图像处理 | OpenCV(计算机视觉核心引擎) |
| 人脸检测 | SeetaFace(国产开源人脸识别引擎) |
| 深度学习推理 | PyTorch(ST-GCN + Yolov5) |
| 后端服务 | .NET Framework |
| 数据库 | SQL Server |
三、智能提示模块 🤖
这是整个系统的 "智慧大脑",负责实时"看懂"用户在做什么姿势。
3.1 模块工作流程

3.2 Yolov5 目标检测算法
为什么选择 Yolov5?
| 特性 | 优势 |
|---|---|
| ⚡ 速度快 | 推理速度可达 140+ FPS,实时检测无压力 |
| 📦 精度高 | mAP-ALL 超过 95%,漏检率极低 |
| 🐍 轻量化 | 模型最小仅约 3.5MB,方便嵌入式部署 |
| 🔧 可定制 | 支持针对特定场景的数据增强和迁移学习 |
核心亮点:本系统对 Yolov5 进行了基于显著性信息改进的优化,进一步提升了复杂背景下的人体检出率。
核心配置
# Yolov5 检测器典型参数配置
yolo_params = {
"confidence_threshold": 0.4, # 置信度阈值,过滤低质量检测框
"nms_threshold": 0.5, # 非极大值抑制,去除重叠框
"input_size": (640, 640), # 输入图像尺寸
"class_filter": ["person"], # 只检测人体类别
}
3.3 AlphaPose 人体姿态估计
骨骼关键点检测
AlphaPose 能够精准检测出人体的 17 个骨骼关键点:

检测器加载模块
# DetectorLoader.py — 检测器统一加载接口
class DetectorLoader:
"""支持多种检测器后端的统一加载器"""
def __init__(self, model_name='yolov5', device='cuda'):
self.model_name = model_name
self.device = device
self.model = self._load_model()
def _load_model(self):
if self.model_name == 'yolov5':
return torch.hub.load('ultralytics/yolov5', 'yolov5s',
pretrained=True, device=self.device)
elif self.model_name == 'alpha':
...
def detect(self, frame):
detections = self.model(frame)
person_dets = detections[detections.class_id == 0]
return person_dets
3.4 DeepSORT 多目标跟踪
跟踪状态机
# Tracker.py — DeepSORT核心实现
class TrackState:
Tentative = 1 # 初始态:证据不足,等待更多帧确认
Confirmed = 2 # 确认态:目标已成功跟踪
Deleted = 3 # 删除态:目标消失或跟踪失败
卡尔曼滤波预测
class Tracker:
def __init__(self, max_iou_distance=0.7, max_age=30, n_init=5):
self.max_iou_dist = max_iou_distance
self.max_age = max_age
self.n_init = n_init
self.kf = KalmanFilter()
self.tracks = []
def update(self, detections):
self.predict()
matches, unmatched_tracks, unmatched_detections = self._match(detections)
for track_idx, det_idx in matches:
self.tracks[track_idx].update(self.kf, detections[det_idx])
for track_idx in unmatched_tracks:
self.tracks[track_idx].mark_missed()
for det_idx in unmatched_detections:
self._initiate_track(detections[det_idx])
self.tracks = [t for t in self.tracks if not t.is_deleted()]
3.5 ST-GCN 时空图卷积神经网络
7类姿态分类输出
# repvgg.py — 最终输出7类动作分类
def create_RepVGG_A0(deploy=False):
model = nn.Sequential(
RepVGG(
num_blocks=[2, 4, 14, 1],
num_classes=1000,
width_multiplier=[0.75, 0.75, 0.75, 2.5],
override_groups_map=None,
deploy=deploy
),
nn.Dropout(p=0.5),
nn.Linear(1000, 7), # 7类姿态输出
nn.Softmax(dim=1)
)
return model
3.6 智能提示策略
| 检测结果 | 提示文案 | Emoji |
|---|---|---|
| ✅ 姿态标准 | "完美!请保持这个姿势~" | 🤗 |
| 👈 头部偏左 | "请轻轻向右转一下头" | 🙃 |
| 👉 头部偏右 | "请轻轻向左转一下头" | 🙃 |
| 📉 低头过多 | "请把下巴微微抬起" | 👆 |
| 📏 头部前倾 | "请保持正脸面对镜头" | 😶 |
| ✋ 手臂抬起 | "请将双手自然放下" | 🤲 |
| ❌ 未检测到人 | "请站到红色框内" | 👀 |
四、证件照生成模块 🪪
4.1 模块工作流程

4.2 身份核验机制
- 读卡器读取:通过华视100UC读卡器读取二代身份证芯片信息(姓名、身份证号、照片)
- 人脸比对:Femto 相机实时采集人像,与身份证芯片照片进行 1:1 比对
- 比对阈值:当相似度超过设定阈值时,核验通过 ✅
安全提示:这一步是防止冒用身份证的关键防线!如果没有这个核验环节,可能会出现"张三用李四的身份证拍证件照"的 bug 😅
核心比对代码
// Idinforead.cpp — 身份证信息读取与核验
class IdInfoReader {
public:
// 读取身份证芯片数据
bool read_card(IdCardInfo& info) {
return hx_read_idcard(&info);
}
// 人脸比对
float compare_face(const cv::Mat& live_face,
const cv::Mat& idcard_face) {
float similarity = seeta_face_compare(
live_face, idcard_face,
seeta::FaceComparison::Threshold::NORMAL
);
return similarity;
}
// 综合核验
bool verify(const cv::Mat& live_face) {
IdCardInfo card_info;
if (!read_card(card_info)) {
show_error("读卡失败,请检查身份证放置");
return false;
}
float sim = compare_face(live_face, card_info.photo);
if (sim < VERIFY_THRESHOLD) {
show_error("人证不一致,请确认是否为本人");
return false;
}
return true;
}
};
4.3 人脸检测与裁剪
SeetaFace 引擎
SeetaFace 是中科院计算所山世光老师团队开源的国产人脸识别引擎,包含:
| 模块 | 功能 |
|---|---|
| 🔍 SeetaFace Detector | 人脸检测(定位人脸框) |
| 🎯 SeetaFace Landmark | 5点/81点关键点定位 |
| 👤 SeetaFace Recognizer | 人脸特征提取与比对 |
证件照规格配置
; YeePoSys.ini — 证件照规格配置
[规格参数]
证件类型 = 护照, 身份证, 签证, 驾照
; 护照规格(默认)
护照宽度 = 354
护照高度 = 472
眼距范围下限 = 82
眼距范围上限 = 118
; 身份证规格
身份证宽度 = 358
身份证高度 = 441
眼距范围下限 = 80
眼距范围上限 = 115
[质量检测]
最小清晰度 = 120
最大过曝率 = 0.15
最小人脸占比 = 0.25
最大人脸占比 = 0.60
核心裁剪代码
// Facecutting.cpp — 人脸区域自动裁剪
class FaceCutter {
public:
cv::Mat auto_crop(const cv::Mat& img,
const seeta::FaceInfo& face,
PhotoSpec spec) {
auto landmarks = face_landmarker.detect(img, face);
float eye_distance = calc_eye_distance(landmarks);
float scale = spec.target_eye_distance / eye_distance;
cv::Point2f center = get_eye_center(landmarks);
cv::Rect crop_box = calc_crop_box(center, spec, scale);
crop_box = clamp_to_image(crop_box, img.size());
cv::Mat cropped = img(crop_box);
cv::Mat resized;
cv::resize(cropped, resized, cv::Size(spec.width, spec.height));
return resized;
}
};
五、证件照处理模块 ✨
5.1 功能矩阵
AI修图不是"换头",而是让你遇见更美的自己。
| 功能 | 算法 | 效果描述 |
|---|---|---|
| 🎨 背景替换 | K-Means 聚类分割 | 蓝/白/红底一键切换 |
| ✨ 皮肤美颜 | 双边滤波 + 细节增强 | 磨皮不失真 |
| 💡 智能调光 | 自适应直方图均衡 | 告别"阴阳脸" |
| 🌟 亮度提升 | Gamma 校正 + 线性拉伸 | 让肤色更通透 |
5.2 K-Means 背景分割
算法原理

核心代码实现
# image.py — K-Means背景分割
def segment_background_kmeans(image, target_color=(255, 204, 153)):
"""
基于K-Means聚类的背景分割与替换
Args:
image: 输入BGR图像
target_color: 目标背景色(蓝底:255,203,153 / 白底:255,255,255 / 红底:204,80,80)
Returns:
背景替换后的图像
"""
lab = cv.cvtColor(image, cv.COLOR_BGR2LAB)
pixel_values = lab.reshape(-1, 3)
pixel_values = np.float32(pixel_values)
criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER,
100, 0.2)
_, labels, centers = cv.kmeans(
pixel_values,
K=2,
bestLabels=None,
criteria=criteria,
attempts=10,
flags=cv.KMEANS_PP_CENTERS
)
labels = labels.reshape(image.shape[:2])
background_label = 0 if centers[0][0] > centers[1][0] else 1
mask = (labels == (1 - background_label)).astype(np.uint8)
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))
mask = cv.morphologyEx(mask, cv.MORPH_CLOSE, kernel)
mask = cv.morphologyEx(mask, cv.MORPH_OPEN, kernel)
mask = cv.GaussianBlur(mask, (3, 3), 0)
result = image.copy()
bg_color = np.array(target_color, dtype=np.uint8)
for c in range(3):
result[:, :, c] = np.where(mask == 0,
bg_color[c],
image[:, :, c])
return result
5.3 双边滤波美颜
为什么选择双边滤波?
| 滤波器 | 保边效果 | 适用场景 |
|---|---|---|
| 高斯滤波 | ❌ 无 | 通用模糊 |
| 均值滤波 | ❌ 无 | 去噪(暴力) |
| 双边滤波 | ✅ 强 | 人像美颜 ✅ |
| 自适应双边 | ✅ 极强 | 高端美颜 |
美颜算法代码
# image.py — 双边滤波美颜
def apply_beauty_filter(image, skin_threshold=0.3):
"""
智能美颜:在保护五官边缘的前提下进行皮肤美化
Args:
image: 输入BGR图像
skin_threshold: 皮肤区域判定阈值
Returns:
美颜后的图像
"""
result = image.copy()
hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
skin_mask = cv.inRange(hsv, lower_skin, upper_skin)
skin_mask = cv.medianBlur(skin_mask, 5)
smoothed = cv.bilateralFilter(
image,
d=9,
sigmaColor=75,
sigmaSpace=75
)
detail = cv.detailEnhance(smoothed, sigma_s=10, sigma_r=0.15)
result = np.where(skin_mask[:, :, np.newaxis] == 255,
detail,
image)
return result.astype(np.uint8)
5.4 质量检测与自动重拍
"不合格的照片,不将就!"
采集完成后,系统会对证件照进行多维度质量检测:
| 检测项 | 指标 | 阈值 | 不合格处理 |
|---|---|---|---|
| 🔍 清晰度 | Laplacian方差 | > 120 | 重拍提示 |
| ☀️ 曝光度 | 过曝像素占比 | < 15% | 重拍提示 |
| 📐 人脸占比 | 人脸区域占比 | 25%-60% | 自动调整 |
| ⚖️ 对称性 | 左右脸对称度 | > 0.85 | 重拍提示 |
// camerause.cpp — 质量检测核心逻辑
class QualityChecker {
public:
bool check_quality(const cv::Mat& photo) {
if (!check_sharpness(photo)) {
show_tip("⚠️ 照片稍模糊,请保持稳定", "请再拍一张");
return false;
}
if (!check_exposure(photo)) {
show_tip("⚠️ 光线过曝/欠曝", "请调整光线或角度");
return false;
}
if (!check_composition(photo)) {
show_tip("📏 人脸位置不对", "请将脸部对准框内");
return false;
}
return true; // 全部通过 ✅
}
private:
double check_sharpness(const cv::Mat& img) {
cv::Mat gray, laplacian;
cv::cvtColor(img, gray, cv.COLOR_BGR2GRAY);
cv::Laplacian(gray, laplacian, CV_64F);
return laplacian.var(); // 方差越大=越清晰
}
double check_exposure(const cv::Mat& img) {
cv::Mat hsv;
cv::cvtColor(img, hsv, cv.COLOR_BGR2HSV);
return cv.countNonZero(hsv[:, :, 2] > 200) / (img.rows * img.cols);
}
};
六、云平台管理模块 ☁️
6.1 系统架构

6.2 核心业务流程
| 阶段 | 角色 | 操作 | 数据流转 |
|---|---|---|---|
| 1️⃣ 预约 | 用户 | 在线预约时间段 | 预约信息 → 云端数据库 |
| 2️⃣ 填报 | 用户 | 到场确认,补充信息 | 身份信息 → 核验模块 |
| 3️⃣ 采集 | 系统 | 身份核验 + 姿态引导 | 人像数据 → 本地处理 |
| 4️⃣ 处理 | 系统 | AI修图 + 质量检测 | 处理结果 → 云端上传 |
| 5️⃣ 获取 | 用户 | 查看/下载/打印 | 成品照片 → 用户账户 |
6.3 管理端核心功能
| 功能模块 | 功能描述 |
|---|---|
| 📊 数据看板 | 实时展示今日采集量、通过率、设备状态 |
| 🖥️ 设备管理 | Femto相机状态监控、读卡器连接管理 |
| 👥 用户管理 | 操作员账号、权限配置、操作日志 |
| 📁 照片管理 | 照片归档、检索、导出、删除 |
| 🔧 系统设置 | 规格模板、检测阈值、提示文案配置 |
七、技术创新亮点 🚀
7.1 创新点一览
| # | 创新点 | 技术方案 | 效果提升 |
|---|---|---|---|
| 1️⃣ | 显著性 Yolov5 | 融合显著性检测增强人体感知 | 复杂背景下检出率提升约 12% |
| 2️⃣ | DeepSORT 跟踪 | 卡尔曼滤波 + IOU 级联匹配 | 多目标跟踪 MOTA > 0.85 |
| 3️⃣ | RepVGG 姿态网络 | 重参数化 + SE 注意力 | 7类姿态准确率 > 94% |
| 4️⃣ | K-Means 背景分割 | LAB 空间聚类 + 泊松融合 | 边缘过渡自然,无明显接缝 |
| 5️⃣ | 交互式美颜 | 皮肤检测遮罩 + 双边滤波 | 磨皮不失真,保留皮肤纹理 |
| 6️⃣ | 质量闭环检测 | Laplacian + 曝光分析 + 构图检查 | 不合格率重拍拦截率 > 98% |
7.2 RepVGG 重参数化技术详解
核心思想:训练时使用多分支结构(3×3卷积 + 1×1卷积 + 恒等映射),推理时通过数学等价变换合并为单卷积,实现"训练复杂、推理简洁"。
# RepVGG推理加速原理
# 训练阶段三路并行:
output = ReLU(SE(Conv3x3(x) + Conv1x1(x) + Identity(x) + BN))
# 推理阶段合并为单卷积(速度提升2-3倍):
output = ReLU(SE(Conv_single(x))) # 只需一次卷积
八、环境配置与部署 ⚙️
8.1 依赖环境
| 组件 | 版本要求 | 说明 |
|---|---|---|
| Python | ≥ 3.8 | 主要 AI 推理环境 |
| PyTorch | ≥ 1.9 | 深度学习框架 |
| OpenCV | ≥ 4.5 | 图像处理核心 |
| Qt | ≥ 5.15 | 桌面 UI 框架 |
| Visual Studio | ≥ 2019 | C++ 编译环境 |
| .NET Framework | ≥ 4.7 | 后端服务框架 |
| SQL Server | ≥ 2016 | 数据库 |
8.2 安装步骤
# 1. 克隆源码
git clone https://github.com/3DCVdeveloper/Skeleton_Portrait-collection.git
cd Skeleton_Portrait-collection
# 2. 安装Python依赖
pip install torch torchvision opencv-python seetaface
pip install -r requirements.txt
# 3. 下载预训练模型权重
# Yolov5: wget https://github.com/ultralytics/yolov5/releases/download/v6.0/yolov5s.pt
# AlphaPose: wget https://github.com/MVIG-SJTU/AlphaPose/releases/download/alphapose/alphapose/AlphaPose
# SeetaFace: wget https://github.com/seetafaceengine/SeetaFace2/releases/download/v2.0/model.tar.gz
# 4. 配置数据库连接
# 编辑 YeePoSys.ini 中的 SQL Server 连接字符串
# 5. 编译C++项目
cd SmartCamera01/
qmake SmartCamera01.pro
make
# 6. 启动系统
./SmartCamera01
九、常见问题与解决方案 💬
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| ❗ 读卡器无响应 | USB未识别/驱动未安装 | 检查设备管理器,重新安装华视驱动 |
| ❗ 人脸检测失败 | 光线过暗/面部遮挡 | 调整补光灯,移除口罩/眼镜 |
| ❗ 姿态一直不合格 | 站位超出检测范围 | 移动到红色框内,保持正视相机 |
| ❗ 背景分割有瑕疵 | 衣服颜色接近背景色 | 选择对比度更高的衣服或切换背景色 |
| ❗ 云端上传失败 | 网络不稳定/存储满 | 检查网络连接,联系管理员清理存储 |
| ❗ 照片模糊 | 手持抖动/光线不足 | 双手握持手机,补充正面光源 |
十、总结与展望 🌅
10.1 项目总结
让每个人都能"优雅"地拍出满意的证件照。
| 维度 | 成果 |
|---|---|
| 🎯 功能完整 | 四大模块覆盖证件照全生命周期 |
| 🧠 算法先进 | Yolov5 + AlphaPose + ST-GCN + RepVGG 技术栈 |
| 🔒 安全可靠 | 身份证双重核验机制 |
| ✨ 体验友好 | 实时智能提示,无需人工干预 |
| ☁️ 管理高效 | 云端协同,设备集中管理 |
10.2 未来展望
| 方向 | 目标 | 预期价值 |
|---|---|---|
| 🌍 多语言支持 | 扩展至英语、日语、韩语等多语种 | 面向出境游客、国际学生群体 |
| 🤳 移动端扩展 | 开发 iOS/Android 拍照 App | 随时随地自拍,线下设备补充 |
| 🎭 虚拟试装 | AR换装、发型模拟 | 丰富用户体验,提升满意度 |
| 📚 持续学习 | 增量学习优化姿态识别模型 | 越用越准,覆盖更多极端场景 |
| 🏥 行业拓展 | 医疗影像、考勤签到等场景延伸 | 从证件照扩展到泛人像采集 |