在 CanMV K210 入门和综合项目中,人脸检测实验是一个很适合拆解的 AI 视觉案例。它不是只验证摄像头能不能打开,也不是只验证模型能不能加载,而是把摄像头采集、图像格式设置、KPU 模型推理、YOLO 后处理、LCD 显示和串口调试串成一条完整链路。
本实验使用 CanMV K210 运行 4.5_face_detect.py。程序通过摄像头采集 RGB 图像,将图像送入 KPU 执行 YOLO 人脸检测模型推理,再把检测到的人脸位置绘制成绿色矩形框显示在 LCD 上。程序还会在画面左上角显示 FPS,方便观察模型推理速度和画面刷新状态。
| 学习目标 | 说明 |
|---|---|
| 理解 AI 视觉流程 | 掌握摄像头采集、图像预处理、KPU 推理、后处理和结果显示之间的关系 |
| 掌握模型加载方式 | 使用 /sd/yolo_face_detect.kmodel 从 SD 卡加载人脸检测模型 |
| 理解 YOLO 后处理 | 通过 anchor、阈值、NMS 等参数完成检测结果筛选 |
| 学会结果显示 | 使用 draw_rectangle() 在 LCD 图像上框选检测到的人脸 |
| 建立调试思路 | 从摄像头、LCD、模型路径、阈值和内存回收等方向排查问题 |
这个实验的价值不只是"框出一张人脸",而是让 AI 模型推理过程变得可观察。摄像头采集到的是图像,KPU 输出的是检测结果,LCD 显示的是框选反馈,串口输出的是调试信息。把这几部分连接起来,就能理解 K210 边缘 AI 项目的基本运行方式。
文章目录
理论基础
人脸检测和普通图像显示实验不同。普通摄像头实验只需要把摄像头画面显示到 LCD 上,而人脸检测需要把图像送入神经网络模型进行推理。K210 芯片中的 KPU 是专门用于神经网络加速的单元,适合运行经过转换后的 kmodel 模型文件。本实验中的 yolo_face_detect.kmodel 就是用于人脸检测的模型文件。
程序运行时,摄像头先采集一帧 320×240 的 RGB 图像。由于模型输入尺寸设置为 320×256,代码中创建了一个 od_img = image.Image(size=(320,256)) 的图像对象,再把摄像头图像绘制到这个对象中。随后调用 od_img.pix_to_ai() 将图像转换成适合 KPU 推理的数据格式,再通过 kpu.run_with_output(od_img) 执行模型推理。
YOLO 检测模型的输出不能直接当作人脸框使用,还需要经过后处理。代码中的 kpu.init_yolo2() 配置了 anchor、输入尺寸、网络尺寸、输出层尺寸、置信度阈值和 NMS 参数。推理完成后,kpu.regionlayer_yolo2() 会返回检测框结果。程序再使用 img.draw_rectangle() 把检测到的人脸区域画到原始图像上,并通过 lcd.display(img) 显示出来。
下面的流程图展示的是本实验的 AI 视觉处理链路。它不是单纯的电路连接图,而是从摄像头输入到 LCD 输出的完整数据流。
摄像头模块
采集 RGB 图像
sensor.snapshot()
获取实时画面
图像适配
绘制到 320×256 输入图
pix_to_ai()
转换为 KPU 输入格式
KPU 推理
yolo_face_detect.kmodel
YOLO 后处理
anchor / threshold / NMS
检测结果
人脸坐标与宽高
LCD 显示
绿色矩形框 + FPS
SD 卡模型文件
/sd/yolo_face_detect.kmodel
串口调试
print(dect)
gc.collect()
内存回收
从这条链路可以看出,人脸检测实验至少包含四个关键条件。摄像头需要正常采集图像,LCD 需要正常显示画面,模型文件需要放在代码指定路径,KPU 参数需要和模型输入尺寸匹配。如果其中任意一环出错,实验现象都会受到影响,例如黑屏、模型加载失败、无检测框、检测不稳定或 FPS 过低。
threshold=0.7 表示检测置信度阈值,阈值越高,误检会减少,但漏检可能增加;阈值越低,更容易检测出目标,但也可能出现错误框。nms_value=0.3 用于抑制重复检测框,避免同一张人脸周围出现多个重叠框。人脸检测效果和光照、距离、角度、画面清晰度、模型文件以及阈值设置都有关系。
硬件设施
本实验围绕 CanMV K210 的 AI 视觉能力展开,主要使用开发板、摄像头模块、LCD 显示屏、SD 卡模型文件和 KPU 神经网络加速器。代码没有使用按键、蜂鸣器、电机、传感器或 WiFi 模块,因此这些外设不作为本节重点。
运行效果截图或实验成品图可以放在这里。发布时建议放置一张 LCD 上显示摄像头画面并框出人脸的图片,这样读者能直接看到模型推理结果。
| 硬件 / 软件 | 作用 | 说明 |
|---|---|---|
| CanMV K210 开发板 | 实验运行平台 | 执行 MicroPython 程序,调用摄像头、LCD 和 KPU |
| 摄像头模块 | 图像采集 | 通过 sensor.snapshot() 获取实时 RGB 图像 |
| LCD 显示屏 | 结果显示 | 显示摄像头画面、FPS 和人脸检测框 |
| KPU 神经网络加速器 | AI 推理 | 加载 kmodel 模型并执行人脸检测推理 |
| SD 卡 | 模型文件存储 | 存放 /sd/yolo_face_detect.kmodel |
| 串口控制台 | 调试输出 | 通过 print("dect:", dect) 查看检测结果 |
sensor |
摄像头控制模块 | 完成摄像头初始化、图像格式和分辨率设置 |
image |
图像处理模块 | 创建输入图像、绘制矩形框和文字 |
lcd |
LCD 显示模块 | 初始化屏幕并显示处理后的图像 |
maix.KPU |
KPU 模块 | 加载模型、初始化 YOLO2、执行推理和获取结果 |
gc |
内存管理模块 | 在循环中执行内存回收,降低长时间运行风险 |
接线和结构关系可以结合下面的占位图补充。实际发布时可以放置摄像头、LCD、SD 卡和开发板的实物连接图,重点展示摄像头排线、LCD 屏幕、SD 卡位置和开发板供电状态。
| 接口 / 资源 | 代码对象 | 对应硬件与说明 |
|---|---|---|
| 摄像头接口 | sensor.reset() / sensor.snapshot() |
初始化摄像头并持续采集图像帧 |
| LCD 接口 | lcd.init() / lcd.display(img) |
显示摄像头画面、FPS 和检测框 |
| KPU 模型文件 | /sd/yolo_face_detect.kmodel |
从 SD 卡加载人脸检测模型 |
| 模型输入图像 | od_img = image.Image(size=(320,256)) |
用于适配 KPU 网络输入尺寸 |
| YOLO 参数 | kpu.init_yolo2(...) |
配置 anchor、阈值、NMS、输入尺寸和输出层尺寸 |
| 检测框绘制 | img.draw_rectangle(...) |
在 LCD 原图上框选识别到的人脸 |
| FPS 显示 | img.draw_string(...) |
在画面左上角显示当前帧率 |
本实验不涉及普通 GPIO 接线,重点不是排查某根信号线是否接错,而是确认视觉链路是否完整。摄像头没有画面时,应优先检查摄像头连接和初始化;LCD 不显示时,应优先检查屏幕初始化和供电;模型加载失败时,应优先检查 SD 卡、模型文件路径和文件名;检测不到人脸时,应优先检查光照、距离、角度和阈值设置。
| 实验现象 | 正常表现 | 异常提示 |
|---|---|---|
| 程序启动 | LCD 初始化,摄像头开始输出画面 | 黑屏时检查 LCD、摄像头和程序初始化 |
| 模型加载 | 程序正常进入主循环,无模型路径报错 | 报错时检查 /sd/yolo_face_detect.kmodel 是否存在 |
| 人脸进入画面 | LCD 上出现绿色矩形框 | 无框时检查光照、距离、角度和阈值 |
| 串口输出 | 检测到人脸时打印 dect: 结果 |
一直无输出可能是没有检测到目标 |
| FPS 显示 | 画面左上角显示帧率 | 帧率过低时减少额外打印或优化显示逻辑 |
| 长时间运行 | 程序持续显示并检测 | 卡顿或内存不足时检查 gc.collect() 和模型资源 |
软件代码
本实验的软件部分以 4.5_face_detect.py 为核心。程序导入 sensor、image、time、lcd、KPU 和 gc,随后完成 LCD 初始化、摄像头初始化、模型加载、YOLO2 参数配置,并在主循环中持续采集图像、执行 KPU 推理、绘制检测框和刷新 LCD。
| 软件环境 | 作用 | 检查重点 |
|---|---|---|
| CanMV IDE | 编辑、运行和调试 K210 程序 | 能识别开发板串口,并能运行基础摄像头程序 |
| CanMV 固件 | 提供 sensor、lcd、KPU 等模块 |
固件需要支持 KPU 模型加载和 YOLO2 后处理 |
| SD 卡 | 存放模型文件 | /sd/yolo_face_detect.kmodel 路径需要与代码一致 |
| 摄像头驱动 | 图像采集 | 能正常显示 QVGA RGB565 图像 |
| LCD 显示环境 | 结果显示 | 能正常显示摄像头画面和绘制内容 |
| 串口终端 | 调试输出 | 能看到检测结果、报错信息或 FPS 相关输出 |
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----湖南创乐博智能科技有限公司----
# 文件名:4.5_face_detect.py
# 版本:V2.0
# author: zhulin
# 说明:CanMv K210 YOLO模型进行人脸检测实验
#####################################################
import sensor, image, time, lcd
from maix import KPU
import gc
lcd.init()
sensor.reset() # 重置并初始化摄像头
# 自动运行,调用sensor.run(0)停止
sensor.set_pixformat(sensor.RGB565) # 设置像素格式为RGB565(或GRAYSCALE)
sensor.set_framesize(sensor.QVGA) # 设置帧大小为QVGA (320x240)
sensor.skip_frames(time = 1000) # 等待设置生效。
clock = time.clock() # 创建一个时钟对象来跟踪FPS。
od_img = image.Image(size=(320,256)) # 设置图像尺寸
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.load_kmodel("/sd/yolo_face_detect.kmodel") # 模型保存在SD卡中,从SD卡中直接加载模型
#kpu.load_kmodel(0x300000,278440) # 我们需要把kmodel模型烧入到0x300000的位置,278440为模型的大小,我们可以通过查看文件属性可以得到;
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.3, classes=1)
while True:
#print("mem free:",gc.mem_free()) # 查询剩余内存
clock.tick() # 更新 FPS 时钟
img = sensor.snapshot()
a = od_img.draw_image(img, 0,0)
od_img.pix_to_ai()
# 对摄像头采集到的图像传递到KPU单元进行yolo模型运算
kpu.run_with_output(od_img)
dect = kpu.regionlayer_yolo2()
fps = clock.fps()
if len(dect) > 0: # 识别到人脸
print("dect:",dect)
for l in dect : # 画矩形框,框起人脸
a = img.draw_rectangle(l[0],l[1],l[2],l[3], color=(0, 255, 0))
a = img.draw_string(0, 0, "%2.1ffps" %(fps), color=(0, 60, 128), scale=2.0) #在LCD上显示帧率
lcd.display(img) # 在LCD显示屏上显示图像
gc.collect() # 内存回收机制
kpu.deinit()
这段程序可以分成三个层级。底层是 LCD、摄像头和模型资源初始化,负责准备 AI 视觉实验所需的硬件和模型文件;中间层是图像采集、图像适配、KPU 推理和 YOLO 后处理,负责把摄像头图像转换成检测结果;上层是矩形框绘制、FPS 显示和 LCD 刷新,负责把推理结果显示给使用者观察。
初始化阶段中,sensor.set_pixformat(sensor.RGB565) 设置摄像头输出 RGB 彩色图像,sensor.set_framesize(sensor.QVGA) 设置画面为 320×240。od_img = image.Image(size=(320,256)) 用于匹配模型输入尺寸,kpu.load_kmodel("/sd/yolo_face_detect.kmodel") 从 SD 卡加载模型文件,kpu.init_yolo2() 则配置 YOLO2 检测参数。
| 函数 / 语句 | 功能 | 对应现象 |
|---|---|---|
lcd.init() |
初始化 LCD 显示屏 | 屏幕准备显示图像 |
sensor.reset() |
重置并初始化摄像头 | 摄像头进入可采集状态 |
sensor.set_pixformat(sensor.RGB565) |
设置摄像头像素格式 | 获取彩色图像 |
sensor.set_framesize(sensor.QVGA) |
设置摄像头分辨率 | 输出 320×240 画面 |
sensor.skip_frames(time=1000) |
等待摄像头设置生效 | 启动后画面更稳定 |
image.Image(size=(320,256)) |
创建 KPU 输入图像 | 适配模型输入尺寸 |
kpu.load_kmodel() |
加载人脸检测模型 | 从 SD 卡读取 kmodel 文件 |
kpu.init_yolo2() |
初始化 YOLO2 后处理参数 | 配置 anchor、阈值、NMS 和输出尺寸 |
sensor.snapshot() |
获取一帧摄像头图像 | 主循环持续采集画面 |
od_img.draw_image(img, 0, 0) |
把摄像头图像绘制到输入图 | 为 KPU 输入做尺寸适配 |
od_img.pix_to_ai() |
转换为 KPU 输入格式 | 图像可以送入 KPU 推理 |
kpu.run_with_output(od_img) |
执行模型推理 | KPU 输出检测结果 |
kpu.regionlayer_yolo2() |
获取 YOLO2 检测结果 | 返回检测框列表 |
img.draw_rectangle() |
绘制人脸检测框 | LCD 上出现绿色矩形框 |
img.draw_string() |
绘制 FPS 文本 | 画面左上角显示帧率 |
lcd.display(img) |
刷新 LCD 显示 | 显示最新检测画面 |
gc.collect() |
执行内存回收 | 降低长时间运行内存压力 |
运行时,程序会不断执行"采集一帧图像、送入 KPU、获取检测框、绘制结果、显示到 LCD"的循环。如果检测到人脸,dect 列表中会包含检测框信息,程序会在串口打印结果,并在画面中用绿色矩形框标出人脸区域。如果没有检测到人脸,LCD 仍然会显示摄像头画面和 FPS,只是不会出现检测框。
需要注意的是,代码末尾的 kpu.deinit() 位于无限循环之后,正常运行时不会自动执行到这一行。如果实验需要主动退出并释放 KPU 资源,可以后续把主循环放入 try...except 或 try...finally 结构中处理。本篇保持原始实验代码结构,便于和课程文件一致。
扩展应用
人脸检测实验常见问题主要集中在摄像头、LCD、模型文件、SD 卡路径、阈值参数和环境光照几个方面。排查时建议先确认摄像头和 LCD 基础功能,再检查模型文件路径,最后再调整阈值、距离和角度。
| 问题现象 | 可能原因 | 处理思路 |
|---|---|---|
| 程序无法运行 | 文件没有传到开发板、固件不支持相关模块、库文件缺失 | 确认主程序在正确目录,检查 CanMV 固件版本和报错行号 |
| LCD 黑屏或无画面 | LCD 未初始化成功、摄像头未输出图像、程序卡在模型加载阶段 | 先运行基础摄像头显示程序,确认 LCD 和摄像头正常 |
| 模型加载失败 | yolo_face_detect.kmodel 没有放到 /sd/,或文件名不一致 |
将模型文件复制到 SD 卡根目录,并核对代码路径 |
| 检测不到人脸 | 光照不足、距离太远、角度过大、阈值过高 | 增强光照,正面对准摄像头,适当靠近目标,必要时降低阈值 |
| 检测结果不稳定 | 人脸移动过快、画面模糊、背景干扰明显 | 固定摄像头位置,保持人脸完整进入画面,减少强逆光 |
| 绿色框位置偏差 | 模型输入尺寸、图像绘制尺寸或坐标映射不匹配 | 保持代码中图像尺寸和 YOLO 参数一致,不随意修改输入尺寸 |
| FPS 较低 | KPU 推理、LCD 刷新和串口打印占用时间 | 减少无关打印,避免在循环中加入过长延时 |
| 程序运行一段时间后卡顿 | 内存碎片或资源占用增加 | 保留 gc.collect(),减少循环中创建不必要对象 |
串口没有 dect: 输出 |
当前画面没有识别到人脸 | 观察 LCD 画面是否有人脸,并调整光照、距离和阈值 |
人脸检测实验的价值不只在于复现实验现象,更在于建立从硬件输入到 AI 判断再到结果输出的项目思路。在掌握基础代码后,可以把它和显示、通信、存储、按键菜单或其他执行模块组合成更完整的作品。
扩展效果图或项目运行截图可以放在这里。发布时建议放置门禁演示、LCD 框选效果、串口检测结果或多人检测画面。
| 应用场景 | 实现思路 | 可扩展能力 |
|---|---|---|
| 智能门禁 | 检测到人脸后触发后续身份识别或开门逻辑 | 可扩展人脸识别、继电器、电磁锁、蜂鸣器提示 |
| 相机人脸框选 | 在 LCD 画面中实时显示人脸框 | 可扩展拍照保存、串口输出坐标、屏幕状态提示 |
| 课堂 AI 演示 | 展示 K210 在本地完成模型推理 | 可用于讲解边缘 AI、模型部署和嵌入式视觉 |
| 人数检测 | 统计当前画面中检测框数量 | 可扩展人数统计、客流提示、区域检测 |
| 机器人交互 | 检测到人脸后让机器人进入交互状态 | 可联动舵机云台、语音提示、LED 状态灯 |
| AI 摄像头状态上报 | 将检测结果通过串口或 WiFi 上传 | 可扩展 TCP 上位机通信、日志记录和可视化显示 |
| 安防提示 | 长时间检测到人脸后触发提示动作 | 可联动蜂鸣器、RGB LED、风扇、电机或报警模块 |
从工程角度看,当前程序已经具备 AI 视觉项目的基本分层。摄像头负责输入,KPU 负责推理,YOLO 后处理负责结果筛选,LCD 负责可视化反馈,串口负责调试输出。后续扩展时,可以单独替换模型、调整阈值、增加通信上传,或者把检测结果转换成外设动作,而不需要重写整个采集和显示流程。
总结
本实验通过 CanMV K210 完成了基于 KPU YOLO 模型的人脸检测,核心能力包括摄像头初始化、RGB 图像采集、KPU 模型加载、YOLO2 后处理配置、检测框绘制、FPS 显示、LCD 刷新和内存回收。程序从摄像头输入开始,把图像送入 KPU 模型推理,再把检测结果绘制到 LCD 画面中,完整展示了 K210 边缘 AI 视觉实验的基本流程。
人脸检测实验是后续 AI 项目的基础入口。掌握这条链路后,可以继续扩展人脸识别、智能门禁、人数统计、机器人交互、AI 摄像头状态上报、上位机通信和视觉联动控制等内容。调试时应按"摄像头画面是否正常、LCD 是否显示、模型文件是否存在、KPU 参数是否匹配、检测阈值是否合适"的顺序排查,这样更容易定位问题。