在 CanMV K210 入门和综合项目中,人脸属性识别实验是一个很适合拆解的 AI 视觉案例。它不是只验证摄像头能否采集画面,也不是单独运行一个模型,而是把摄像头初始化、图像采集、人脸检测、人脸裁剪、关键点定位、仿射对齐、属性分类和 LCD 显示串成一条完整流程。通过这个实验,可以理解 K210 在边缘端运行多模型视觉任务的基本方式。
本实验使用 CanMV K210 运行 4.10_face_attribute.py。程序先通过 yolo_face_detect.kmodel 检测人脸位置,再通过 ld5.kmodel 检测人脸 5 个关键点,随后使用仿射变换把人脸对齐到标准姿态,最后通过 fac.kmodel 输出性别、张嘴、微笑、眼镜等属性判断结果。LCD 画面中会叠加人脸框、关键点、属性文本和 FPS 信息,便于观察 AI 推理结果与图像画面之间的对应关系。
| 学习目标 | 说明 |
|---|---|
| 理解多模型串联 | 掌握人脸检测、关键点检测和属性分类三个模型之间的数据传递关系 |
| 掌握图像采集流程 | 使用 sensor 初始化摄像头,并持续获取实时图像帧 |
| 理解关键点对齐 | 通过 5 个关键点和标准人脸坐标计算仿射变换矩阵 |
| 掌握属性分类输出 | 使用属性模型输出性别、张嘴、微笑、眼镜等分类结果 |
| 建立 AI 视觉调试思路 | 从模型路径、图像输入、检测框、关键点、属性阈值和 FPS 定位问题 |
这个实验的重点不是简单显示"识别成功",而是理解一张摄像头图像如何经过多轮 AI 推理变成可视化结果。人脸框说明检测模型找到了目标,关键点说明模型定位到了眼睛、鼻子和嘴角位置,仿射变换让人脸输入更接近属性模型训练时的标准姿态,属性文本则是最终分类结果。需要注意,这类属性识别结果适合教学演示和算法理解,不适合作为严肃身份判断、权限判断或敏感决策依据。
文章目录
理论基础
人脸属性识别并不是一个单独步骤,而是一条多阶段视觉处理链路。摄像头采集到的是完整画面,画面中可能有人脸、背景、光照变化和其他干扰物。程序需要先找到人脸所在位置,再把人脸区域从原图中裁剪出来。直接把裁剪结果送入属性模型并不稳定,因为人脸可能有角度偏转、距离变化或姿态差异,因此还需要通过关键点检测和仿射变换进行对齐。
本实验中,第一个模型 yolo_face_detect.kmodel 负责人脸检测,输出人脸矩形框。第二个模型 ld5.kmodel 负责检测 5 个关键点,通常对应两只眼睛、鼻子和两个嘴角。程序把这些关键点和标准人脸关键点 dst_point 做匹配,计算出仿射变换矩阵,再用 image.warp_affine_ai() 把人脸区域校正成更规整的 128×128 图像。第三个模型 fac.kmodel 才负责属性分类。
FACE_PIC_SIZE = 128 表示属性模型和关键点对齐阶段使用 128×128 的人脸输入尺寸。RATIO = 0.08 表示在人脸检测框基础上向外扩展一定比例,避免裁剪过紧导致额头、下巴或边缘信息丢失。KPU.sigmoid() 用于把模型输出转换为 0 到 1 之间的概率值,代码中使用 0.7 作为属性判断阈值,超过阈值时显示正向标签,低于阈值时显示反向标签。
摄像头采集
RGB565 QVGA 图像
图像准备
复制到 320×256 输入图
人脸检测模型
yolo_face_detect.kmodel
扩大人脸框
extend_box / RATIO
裁剪并缩放人脸
128×128
关键点模型
ld5.kmodel
5点人脸对齐
仿射变换
属性分类模型
fac.kmodel
属性概率判断
sigmoid + 0.7阈值
LCD叠加显示
人脸框 / 关键点 / 属性 / FPS
模型文件
/sd/*.kmodel
内存管理
gc.collect() / del临时图像
这张流程图展示的是 AI 视觉数据链路。摄像头负责提供原始图像,人脸检测模型负责找到人脸区域,关键点模型负责给出对齐依据,属性模型负责输出分类结果,LCD 负责把检测框、关键点和属性文字显示出来。整个流程中,模型文件、图像尺寸、内存释放和显示绘制都会影响实验稳定性。
从工程角度看,这类程序比普通传感器实验更依赖资源文件。GPIO 实验通常检查接线即可,而 KPU 模型实验必须同时检查摄像头、LCD、SD 卡、模型路径、模型输入尺寸和运行内存。只要其中一个环节不匹配,就可能出现模型加载失败、检测不到人脸、属性结果不稳定或 FPS 明显下降。
硬件设施
本实验围绕 CanMV K210、摄像头模块、LCD 显示屏、SD 卡模型文件和 KPU 推理能力展开。代码没有使用 GPIO 引脚控制外部 LED、蜂鸣器、电机或传感器,因此硬件重点不是传统接线表,而是图像采集、模型加载、AI 推理和屏幕显示这几个环节。
这里适合放置一张实验运行效果图,画面中应能看到摄像头采集到的人脸、LCD 上的人脸框、关键点和属性文字。发布文章时,建议使用实际运行截图替换下面的占位图。
| 硬件 / 软件 | 作用 | 说明 |
|---|---|---|
| CanMV K210 开发板 | 实验运行平台 | 执行 MicroPython 程序,完成摄像头采集、KPU 推理和 LCD 显示 |
| 摄像头模块 | 图像采集设备 | 通过 sensor.snapshot() 持续获取实时画面 |
| LCD 显示屏 | 结果显示设备 | 显示摄像头画面、人脸框、关键点、属性文字和 FPS |
| SD 卡 | 模型文件存储 | 存放 /sd/yolo_face_detect.kmodel、/sd/ld5.kmodel、/sd/fac.kmodel |
| KPU 神经网络加速器 | AI 推理核心 | 加载 kmodel 模型并执行人脸检测、关键点检测和属性分类 |
| 串口控制台 | 调试输出窗口 | 输出模型加载状态、人脸检测框和调试信息 |
sensor |
摄像头控制模块 | 初始化摄像头,设置 RGB565、QVGA,并获取图像帧 |
image |
图像处理模块 | 完成裁剪、缩放、仿射变换、矩形框和文字绘制 |
lcd |
屏幕显示模块 | 将处理后的图像显示到 LCD |
maix.KPU |
AI 推理模块 | 创建 KPU 对象、加载模型、执行推理和后处理 |
gc |
内存管理模块 | 清理临时对象,降低图像处理和多模型推理中的内存压力 |
实验中用到的资源文件比接线更关键。三个模型文件必须放在代码指定路径下,文件名也要保持一致。程序中使用的是 /sd/ 路径,因此需要确认 SD 卡已经插入,模型文件已经复制完成,并且 CanMV 能正常访问这些文件。
| 资源 / 接口 | 代码对象 | 对应硬件与说明 |
|---|---|---|
| 摄像头接口 | sensor.reset() / sensor.snapshot() |
初始化摄像头并持续采集图像帧 |
| LCD 接口 | lcd.init() / lcd.display(img) |
显示实时画面、检测框、关键点和属性文字 |
| 人脸检测模型 | /sd/yolo_face_detect.kmodel |
负责检测画面中的人脸位置 |
| 关键点模型 | /sd/ld5.kmodel |
负责输出人脸 5 个关键点 |
| 属性模型 | /sd/fac.kmodel |
负责输出性别、张嘴、微笑、眼镜等属性结果 |
| KPU 对象 | kpu |
加载并运行人脸检测模型 |
| KPU 对象 | ld5_kpu |
加载并运行 5 关键点模型 |
| KPU 对象 | fac_kpu |
加载并运行属性分类模型 |
| 临时图像 | od_img |
为人脸检测模型准备 320×256 输入图像 |
| 人脸裁剪图 | face_cut / face_cut_128 |
裁剪人脸区域并缩放到属性模型需要的尺寸 |
这里可以补充一张模型文件或硬件准备截图,例如 SD 卡中的 kmodel 文件路径、CanMV IDE 的文件管理界面,或者摄像头和 LCD 的连接状态。AI 视觉实验出现问题时,模型文件路径错误比代码语法错误更常见。
| 实验现象 | 正常表现 | 异常提示 |
|---|---|---|
| 程序启动 | 串口输出 ready load model,模型依次加载 |
报模型加载错误时,优先检查 /sd/ 路径和文件名 |
| 摄像头运行 | LCD 显示实时彩色画面 | 黑屏或花屏时检查摄像头、LCD 初始化和连接状态 |
| 检测到人脸 | LCD 上出现绿色人脸框 | 一直无框时检查光照、距离、脸部角度和检测阈值 |
| 关键点显示 | 人脸上显示蓝色十字关键点 | 关键点偏移时检查人脸框裁剪范围和姿态角度 |
| 属性显示 | 人脸框右侧显示属性文字 | 结果不稳定时调整距离、光照和正脸角度 |
| FPS 显示 | 左上角显示帧率 | FPS 过低时减少打印和无关绘制,保持合适分辨率 |
| 内存压力 | 程序能持续运行 | 运行一段时间后异常时检查临时图像释放和模型数量 |
软件代码
本实验的软件部分以 4.10_face_attribute.py 为核心。程序导入 sensor、image、time、lcd、KPU 和 gc,先完成 LCD、摄像头和三个 KPU 模型初始化,再在循环中持续采集画面、检测人脸、定位关键点、对齐人脸、识别属性并显示结果。
| 软件环境 | 作用 | 检查重点 |
|---|---|---|
| CanMV IDE | 编辑、运行和调试程序 | 能看到串口输出和 LCD 图像显示 |
| CanMV 固件 | 提供 sensor、image、lcd、maix.KPU 等模块 |
固件需要支持当前 KPU API 和图像处理函数 |
| SD 卡 | 存储 kmodel 模型文件 | 三个模型文件需要放在 /sd/ 目录 |
| 摄像头驱动 | 采集实时图像 | sensor.snapshot() 能正常返回图像 |
| LCD 显示模块 | 显示检测结果 | lcd.display(img) 能正常刷新画面 |
| KPU 模型文件 | 执行 AI 推理 | 模型文件名和代码中的 load_kmodel() 路径一致 |
代码中比较重要的配置参数如下。理解这些参数后,后续调整检测稳定性、显示效果和模型输入会更清晰。
| 参数名 | 当前值 | 作用说明 |
|---|---|---|
FACE_PIC_SIZE |
128 |
属性识别和人脸对齐阶段使用的人脸图像尺寸 |
RATIO |
0.08 |
人脸检测框向外扩展比例,避免裁剪过紧 |
threshold |
0.7 |
YOLO 人脸检测置信度阈值 |
nms_value |
0.2 |
YOLO 后处理中抑制重叠框的参数 |
anchor |
9 组锚框参数 | 人脸检测模型的 YOLO2 锚框配置 |
dst_point |
5 个标准点 | 用于人脸关键点对齐的目标坐标 |
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----湖南创乐博智能科技有限公司----
# 文件名:4.10_face_attribute.py
# 版本:V2.0
# author: zhulin
# 说明:CanMv K210人脸属性识别实验
#####################################################
import sensor, image, time, lcd
from maix import KPU
import gc
lcd.init() # 初始化LCD显示屏
sensor.reset() # 复位并初始化摄像头
sensor.set_pixformat(sensor.RGB565) # 设置摄像头输出格式为 RGB565
sensor.set_framesize(sensor.QVGA) # 设置摄像头输出大小为 QVGA (320x240)
sensor.skip_frames(time = 1000) # 等待摄像头稳定
clock = time.clock() # 创建一个clock对象,用来计算帧率
#人脸检测模型需要320*256图输入,这里初始化一个image
od_img = image.Image(size=(320,256), copy_to_fb=False)
anchor = (0.893, 1.463, 0.245, 0.389, 1.55, 2.58, 0.375, 0.594, 3.099, 5.038, 0.057, 0.090, 0.567, 0.904, 0.101, 0.160, 0.159, 0.255)
# 创建一个kpu对象,用于人脸检测
kpu = KPU()
print("ready load model")
kpu.load_kmodel("/sd/yolo_face_detect.kmodel") # 加载模型
# yolo2初始化
kpu.init_yolo2(anchor, anchor_num=9, img_w=320, img_h=240, net_w=320 , net_h=256 ,layer_w=10 ,layer_h=8, threshold=0.7, nms_value=0.2, classes=1)
ld5_kpu = KPU() # 创建一个kpu对象,用于人脸5关键点检测
print("ready load model")
ld5_kpu.load_kmodel("/sd/ld5.kmodel")
fac_kpu = KPU() # 创建一个kpu对象,用于人脸属性检测
print("ready load model")
fac_kpu.load_kmodel("/sd/fac.kmodel")
pos_face_attr = ["Male ", "Mouth Open ", "Smiling ", "Glasses"]
neg_face_attr = ["Female ", "Mouth Closed", "No Smile", "No Glasses"]
# 标准人脸关键点坐标
FACE_PIC_SIZE = 128
dst_point =[(int(38.2946 * FACE_PIC_SIZE / 112), int(51.6963 * FACE_PIC_SIZE / 112)),
(int(73.5318 * FACE_PIC_SIZE / 112), int(51.5014 * FACE_PIC_SIZE / 112)),
(int(56.0252 * FACE_PIC_SIZE / 112), int(71.7366 * FACE_PIC_SIZE / 112)),
(int(41.5493 * FACE_PIC_SIZE / 112), int(92.3655 * FACE_PIC_SIZE / 112)),
(int(70.7299 * FACE_PIC_SIZE / 112), int(92.2041 * FACE_PIC_SIZE / 112)) ]
RATIO = 0.08 # 人脸外接框放大比例
def extend_box(x, y, w, h, scale):
x1_t = x - scale*w
x2_t = x + w + scale*w
y1_t = y - scale*h
y2_t = y + h + scale*h
x1 = int(x1_t) if x1_t>1 else 1
x2 = int(x2_t) if x2_t<320 else 319
y1 = int(y1_t) if y1_t>1 else 1
y2 = int(y2_t) if y2_t<256 else 255
cut_img_w = x2-x1+1
cut_img_h = y2-y1+1
return x1, y1, cut_img_w, cut_img_h
while 1:
gc.collect()
#print("mem free:",gc.mem_free())
clock.tick() # 更新计算帧率的clock
img = sensor.snapshot() # 拍照,获取一张图像
a = od_img.draw_image(img, 0,0) # 将img图像写到od_img图像的坐标(0,0)位置处
od_img.pix_to_ai() # 对rgb565的image生成ai运算需要的r8g8b8格式存储
kpu.run_with_output(od_img) # 对输入图像进行kpu运算
dect = kpu.regionlayer_yolo2() # yolo2后处理
fps = clock.fps() # 获取帧率
if len(dect) > 0:
print("dect:",dect)
for l in dect :
# 对检测到的人脸框扩大RATIO倍后裁剪
x1, y1, cut_img_w, cut_img_h = extend_box(l[0], l[1], l[2], l[3], scale=RATIO) # 扩大人脸框
face_cut = img.cut(x1, y1, cut_img_w, cut_img_h) # 从img中裁剪出人脸图
a = img.draw_rectangle(l[0],l[1],l[2],l[3], color=(0, 255, 0)) # 画人脸框
face_cut_128 = face_cut.resize(128, 128) # 对人脸图调整大小到128*128
face_cut_128.pix_to_ai() # 对rgb565格式的128人脸图生成ai运算需要的rgb888格式存储
out = ld5_kpu.run_with_output(face_cut_128, getlist=True) # kpu运算并获取结果
#print("out:",len(out))
face_key_point = []
for j in range(5): # 根据结果算出人脸5关键点,并在图中标出
x = int(KPU.sigmoid(out[2 * j])*cut_img_w + x1)
y = int(KPU.sigmoid(out[2 * j + 1])*cut_img_h + y1)
a = img.draw_cross(x, y, size=5, color=(0, 0, 255))
face_key_point.append((x,y))
T = image.get_affine_transform(face_key_point, dst_point) #由关键点算出变换矩阵
a = image.warp_affine_ai(img, face_cut_128, T) # 相似变换修正人脸图
# face_cut_128.ai_to_pix()
# img.draw_image(face_cut_128, 0,0)
out2 = fac_kpu.run_with_output(face_cut_128, getlist=True) # 检测人脸属性获取结果
del face_key_point
if out2 is not None:
for i in range(4):
th = KPU.sigmoid(out2[i])
if th >= 0.7:
a = img.draw_string(l[0]+l[2], l[1]+i*16, "%s" %(pos_face_attr[i]), color=(255, 0, 0), scale=1.5)
else:
a = img.draw_string(l[0]+l[2], l[1]+i*16, "%s" %(neg_face_attr[i]), color=(0, 0, 255), scale=1.5)
del (face_cut_128)
del (face_cut)
a = img.draw_string(0, 0, "%2.1ffps" %(fps), color=(0, 60, 255), scale=2.0)
lcd.display(img)
# 创建的kpu对象去初始化,释放模型内存
kpu.deinit()
ld5_kpu.deinit()
fac_kpu.deinit()
这里可以放置一张 LCD 识别结果截图。截图中建议保留人脸框、关键点、属性文字和 FPS 信息,这样读者能直接把代码里的 draw_rectangle()、draw_cross()、draw_string() 和 lcd.display() 对应到实际画面。
这段程序可以理解成三个层级。底层是摄像头和 LCD 初始化,负责采集图像并显示处理结果;中间层是三个 KPU 模型,分别完成人脸检测、关键点检测和属性识别;上层是图像绘制和调试输出,把模型结果叠加到 LCD 画面,并通过串口输出检测框信息。
extend_box() 是人脸裁剪前的重要处理函数。检测模型输出的人脸框可能刚好贴近脸部边缘,如果直接裁剪,属性模型可能拿不到完整人脸区域。RATIO = 0.08 会让检测框向外扩展一定比例,再根据画面边界限制坐标范围,避免裁剪区域越界。这个处理能让后续关键点检测和属性识别更稳定。
dst_point 保存了标准人脸关键点位置。程序检测到当前人脸的 5 个关键点后,通过 image.get_affine_transform(face_key_point, dst_point) 计算变换矩阵,再调用 image.warp_affine_ai() 对人脸图像做姿态校正。这个步骤是属性识别稳定性的关键。如果人脸没有对齐,眼睛、嘴巴和眼镜的位置变化会更大,属性模型输出也更容易波动。
属性分类部分使用 fac_kpu.run_with_output(face_cut_128, getlist=True) 获取结果,再对前 4 个输出使用 KPU.sigmoid() 转成概率。代码中把 0.7 作为判断阈值,达到阈值时显示 pos_face_attr 中的标签,没有达到阈值时显示 neg_face_attr 中的标签。LCD 上的文字并不是人工规则判断,而是属性模型对当前对齐人脸图像的分类输出。
| 函数 / 对象 | 功能 | 对应现象 |
|---|---|---|
lcd.init() |
初始化 LCD 显示屏 | LCD 可以显示实时画面 |
sensor.reset() |
初始化摄像头 | 摄像头开始采集图像 |
sensor.set_pixformat(sensor.RGB565) |
设置彩色图像格式 | 图像以 RGB565 格式进入处理流程 |
sensor.set_framesize(sensor.QVGA) |
设置 320×240 图像尺寸 | LCD 显示 QVGA 画面 |
image.Image(size=(320,256)) |
创建检测模型输入图像 | 为 YOLO 人脸检测模型准备输入 |
kpu.init_yolo2() |
初始化 YOLO2 后处理参数 | 人脸检测模型能输出检测框 |
extend_box() |
扩大人脸检测框 | 裁剪区域包含更完整的人脸 |
img.cut() |
裁剪人脸区域 | 得到单张人脸图像 |
resize(128, 128) |
缩放人脸图像 | 满足关键点和属性模型输入尺寸 |
ld5_kpu.run_with_output() |
运行 5 关键点模型 | LCD 上绘制眼睛、鼻子、嘴角关键点 |
image.get_affine_transform() |
计算人脸对齐矩阵 | 为仿射校正提供变换关系 |
image.warp_affine_ai() |
对齐人脸图像 | 属性模型获得更标准的人脸输入 |
fac_kpu.run_with_output() |
运行属性分类模型 | 输出性别、张嘴、微笑、眼镜等属性结果 |
KPU.sigmoid() |
将输出转换成概率 | 根据 0.7 阈值判断显示哪一类属性 |
lcd.display(img) |
显示叠加后的图像 | LCD 显示人脸框、关键点、属性和 FPS |
代码末尾写有 kpu.deinit()、ld5_kpu.deinit() 和 fac_kpu.deinit(),用于释放模型内存。不过当前程序主体是 while 1 无限循环,正常运行时通常不会执行到这几行。后续如果加入按键退出、异常捕获或菜单切换,可以把模型释放逻辑放到退出流程中,这样更利于长期运行和多实验切换。
扩展应用
人脸属性识别实验常见问题主要集中在模型路径、摄像头画面、光照、人脸距离、输入尺寸、内存和推理速度。排查时不建议直接修改整段代码,应先确认模型是否成功加载,再观察 LCD 画面是否正常,随后检查是否有人脸框、关键点和属性文字。
| 问题现象 | 可能原因 | 处理思路 |
|---|---|---|
| 模型加载失败 | kmodel 文件没有放到 /sd/,文件名不一致,SD 卡未识别 |
核对 /sd/yolo_face_detect.kmodel、/sd/ld5.kmodel、/sd/fac.kmodel 是否存在 |
| LCD 没有画面 | LCD 初始化失败、摄像头未正常采集、程序未进入主循环 | 先运行简单摄像头显示程序,确认 sensor.snapshot() 和 lcd.display() 正常 |
| 一直检测不到人脸 | 光照不足、人脸太远、角度过大、检测阈值偏高 | 保持正脸、增加光照、拉近距离,必要时调整 YOLO 阈值 |
| 有人脸框但没有属性文字 | 关键点检测失败、裁剪区域异常、属性模型未输出 | 观察关键点是否绘制正常,检查 face_cut_128 和 out2 是否有效 |
| 关键点位置偏移 | 人脸框裁剪不完整、侧脸角度过大、画面模糊 | 保持人脸正对摄像头,适当增大 RATIO,改善光照和清晰度 |
| 属性结果跳动 | 光照变化、表情变化、人脸角度变化、阈值设置敏感 | 固定摄像头和人脸位置,保持稳定光照,必要时调整属性判断阈值 |
| FPS 较低 | 同时运行三个模型,图像绘制和串口打印较多 | 减少无关 print(),减少多余绘制,保持 QVGA 分辨率 |
| 运行一段时间异常 | 临时图像对象较多,内存压力偏大 | 保留 gc.collect() 和 del 临时对象,减少额外图像缓存 |
| 属性标签不符合预期 | 模型输出受训练数据、光照、姿态和遮挡影响 | 将结果作为实验演示,不作为严肃身份、性别或权限判断依据 |
人脸属性识别实验的价值不只在于复现 LCD 上的属性文字,更在于建立多模型 AI 视觉项目的拆解思路。复杂任务可以被拆成检测、裁剪、对齐、分类和显示几个阶段,每个阶段都有明确输入和输出。掌握这个结构后,后续替换成口罩检测、表情识别、疲劳检测、门禁提示或课堂演示,都可以沿用类似流程。
| 应用场景 | 实现思路 | 可扩展能力 |
|---|---|---|
| AI 视觉课堂演示 | 展示人脸检测、关键点和属性分类的完整链路 | 可用于讲解 KPU 模型部署、图像预处理和推理结果显示 |
| 智能相机实验 | 在 LCD 上实时叠加人脸框、关键点和属性文字 | 可扩展拍照保存、属性统计或串口输出 |
| 表情状态提示 | 使用 Smiling、No Smile、Mouth Open 等属性作为交互输入 |
可扩展蜂鸣器、LED 或屏幕提示 |
| 眼镜属性演示 | 通过 Glasses 和 No Glasses 展示二分类模型结果 |
可用于讲解模型概率、阈值和误判边界 |
| 门禁界面提示 | 在检测到人脸后显示属性和状态信息 | 可结合人脸识别模型做身份验证,但属性结果不应作为权限判断依据 |
| 多模型部署教学 | 同时运行人脸检测、关键点检测和属性分类模型 | 可讲解模型文件管理、内存管理和推理顺序 |
| 人机交互原型 | 根据笑脸、张嘴等状态触发简单反馈 | 可扩展按键、LCD 菜单、蜂鸣器和串口通信 |
| 边缘 AI 调试平台 | 通过 FPS 和 LCD 叠加显示观察模型运行效果 | 可继续加入日志记录、上位机调试或模型替换实验 |
从工程角度看,建议保持"采集、检测、对齐、分类、显示"分层。摄像头采集只负责拿到画面,人脸检测只负责输出框,关键点模型只负责输出对齐依据,属性模型只负责输出分类结果,LCD 只负责展示。这样的结构便于后续替换模型、调整阈值、优化显示内容或增加外设联动。
总结
本实验通过 CanMV K210 完成了人脸属性识别基础验证,核心能力包括摄像头初始化、LCD 显示、KPU 模型加载、YOLO2 人脸检测、检测框扩展、人脸裁剪、5 关键点定位、仿射对齐、属性分类和 FPS 显示。它展示了 K210 不只是运行单个模型,也可以把多个模型按顺序组合成完整 AI 视觉流程。
相比普通硬件输入输出实验,人脸属性识别更能体现嵌入式 AI 项目的工程特点。模型文件路径、输入图像尺寸、检测框质量、关键点对齐效果、属性阈值和内存管理都会影响最终结果。调试时应先确认模型加载和画面显示,再逐步观察人脸框、关键点、属性文字和 FPS。后续课程可以在这个基础上继续扩展人脸识别、口罩检测、表情交互、LCD 菜单、蜂鸣器反馈、数据记录和边缘 AI 综合项目。