在 CanMV K210 入门和综合项目中,YOLO 口罩识别实验是一个典型的 AI 视觉案例。它不是只验证摄像头能不能显示画面,而是把摄像头采集、模型加载、KPU 推理、结果后处理、类别判断和 LCD 显示串成完整流程。通过这个实验,可以理解 K210 如何在边缘端运行目标检测模型,并把识别结果直接显示到屏幕上。
本实验使用 CanMV K210 运行 4.9_mask_detection.py。程序加载 /sd/detect_5.kmodel 口罩识别模型,通过摄像头检测人脸佩戴口罩状态,并在屏幕上绘制检测框和类别文字。检测到佩戴口罩时,画面中显示绿色框和 with mask;检测到未佩戴口罩时,画面中显示红色框和 without mask。实验重点是理解模型文件、KPU 推理、YOLO 后处理、检测框、类别结果和置信度阈值之间的关系。
| 学习目标 | 说明 |
|---|---|
| 理解 AI 视觉检测流程 | 认识摄像头采集、模型推理、后处理和结果显示之间的关系 |
| 掌握 KPU 模型加载 | 使用 KPU() 创建对象,并通过 load_kmodel() 加载模型文件 |
| 理解 YOLO 检测结果 | 认识检测框、类别编号、阈值、NMS 和类别显示的作用 |
| 学会显示识别结果 | 在 LCD 上绘制人脸框、类别文字和 FPS 信息 |
| 建立边缘 AI 项目思路 | 为人脸检测、物体识别、门禁提示和智能相机实验打基础 |
这个实验属于教学演示案例,主要用于理解 K210 的模型部署和图像检测流程。实际工程中的口罩佩戴检测还需要考虑模型训练数据、识别准确率、光照条件、摄像头角度、误检漏检和应用场景规范,不能把单个课堂实验直接等同于正式检测系统。
文章目录
理论基础
YOLO 口罩识别实验可以理解成"摄像头图像输入 + 神经网络模型推理 + 检测结果显示"的组合。摄像头负责获取实时画面,KPU 负责执行模型推理,YOLO 后处理负责把模型输出转换成检测框和类别结果,LCD 负责把最终结果显示出来。
K210 芯片内部带有 KPU 神经网络加速器,适合运行经过适配的 kmodel 模型。本实验中的 /sd/detect_5.kmodel 就是需要加载到 KPU 中运行的模型文件。程序启动后,先初始化 LCD 和摄像头,再创建 KPU 对象,加载模型,并通过 init_yolo2() 设置 anchor、输入尺寸、输出层尺寸、检测阈值、NMS 参数和类别数量。
YOLO 检测结果通常包含目标位置和类别信息。当前代码中,l[0]、l[1]、l[2]、l[3] 用于绘制检测框,l[4] 用于判断类别。当 l[4] 为真时,程序认为目标属于 with mask;否则显示为 without mask。代码通过不同颜色区分类别:绿色表示佩戴口罩,红色表示未佩戴口罩。
摄像头模块
采集实时画面
sensor 初始化
RGB565 / QVGA
sensor.snapshot()
获取图像帧
图像复制到 od_img
适配模型输入
pix_to_ai()
转换为 AI 推理格式
KPU 模型推理
run_with_output
YOLO2 后处理
regionlayer_yolo2
检测结果判断
with mask / without mask
LCD 绘制结果
检测框 / 类别文字 / FPS
串口输出
检测结果与调试信息
模型文件
/sd/detect_5.kmodel
YOLO 参数
anchor / threshold / NMS / classes
这条链路可以从 AI 视觉项目的角度理解。摄像头采集到的原始画面不能直接得到"是否戴口罩"的答案,需要经过模型输入格式转换、KPU 推理和 YOLO 后处理。最终程序得到检测框和类别结果后,才把它们绘制到 LCD 画面上。影响识别效果的因素主要包括模型文件是否正确、光照是否充足、人脸是否完整入画、目标距离是否合适、阈值是否过高,以及摄像头画面是否清晰。
硬件设施
本实验围绕 CanMV K210、摄像头模块、LCD 显示屏和 KPU 模型文件展开。代码没有使用普通 GPIO、蜂鸣器、电机、I2C 传感器或外接按键,因此硬件重点不在引脚接线,而在摄像头、LCD、SD 卡模型文件和开发板运行环境。
实际发布时,可以在这里放入 CanMV K210、摄像头、LCD 和 SD 卡模型文件准备状态的图片。检查时重点关注摄像头排线方向、LCD 是否正常显示、SD 卡是否插入,以及 /sd/detect_5.kmodel 是否存在。
| 硬件 / 软件 | 作用 | 说明 |
|---|---|---|
| CanMV K210 开发板 | 实验运行平台 | 执行 MicroPython 程序,完成图像采集、KPU 推理和结果显示 |
| 摄像头模块 | 图像采集 | 通过 sensor.snapshot() 获取实时画面 |
| LCD 显示屏 | 结果显示 | 显示摄像头画面、检测框、类别文字和 FPS |
| KPU 神经网络加速器 | AI 推理 | 加载 kmodel 模型并执行目标检测推理 |
/sd/detect_5.kmodel |
模型文件 | 口罩识别模型,需要放到 SD 卡指定路径 |
sensor 模块 |
摄像头控制 | 完成摄像头复位、像素格式设置、分辨率设置和图像采集 |
image 模块 |
图像处理 | 提供图像对象、绘制矩形、绘制文字和图像格式转换能力 |
lcd 模块 |
屏幕显示 | 初始化 LCD,并显示处理后的图像 |
maix.KPU |
AI 推理接口 | 创建 KPU 对象,加载模型并执行 YOLO2 推理 |
gc 模块 |
内存管理 | 在循环中回收内存,降低长时间运行时的内存压力 |
本实验的关键资源不是普通传感器线,而是摄像头画面和模型文件。摄像头用于输入图像,模型文件用于执行口罩识别,LCD 用于显示结果。如果程序无法运行,应优先检查模型路径、摄像头初始化和 LCD 显示,而不是排查普通 GPIO。
| 接口 / 资源 | 代码对象 | 对应硬件与说明 |
|---|---|---|
| 摄像头接口 | sensor.reset() |
初始化摄像头模块 |
| 图像采集 | sensor.snapshot() |
获取实时图像帧 |
| 图像格式 | sensor.set_pixformat(sensor.RGB565) |
设置摄像头输出为 RGB565 彩色图像 |
| 图像分辨率 | sensor.set_framesize(sensor.QVGA) |
设置摄像头输出大小为 320×240 |
| AI 输入图像 | od_img = image.Image(size=(320,256), copy_to_fb=False) |
创建适配模型输入尺寸的图像缓存 |
| AI 格式转换 | od_img.pix_to_ai() |
将图像转换成 KPU 推理需要的格式 |
| 模型文件 | kpu.load_kmodel("/sd/detect_5.kmodel") |
从 SD 卡加载口罩识别模型 |
| YOLO 参数 | kpu.init_yolo2(...) |
设置 anchor、输入尺寸、阈值、NMS 和类别数量 |
| LCD 显示 | lcd.display(img) |
显示摄像头画面和检测结果 |
实验运行时,LCD 上应能看到摄像头画面。人脸进入画面后,如果模型识别到目标,会在画面中绘制检测框和类别文字。佩戴口罩时显示绿色框和 with mask,未佩戴口罩时显示红色框和 without mask。
| 实验现象 | 正常表现 | 异常提示 |
|---|---|---|
| 程序启动 | 串口输出 ready load model,LCD 显示摄像头画面 |
黑屏或报错时检查 LCD、摄像头和模型文件 |
| 模型加载 | 程序能正常进入主循环 | 加载失败时检查 /sd/detect_5.kmodel 路径和文件名 |
| 佩戴口罩进入画面 | 画面出现绿色框和 with mask |
无识别时检查光照、距离和人脸是否完整入画 |
| 未佩戴口罩进入画面 | 画面出现红色框和 without mask |
类别错误时检查模型效果、角度和遮挡情况 |
| 串口输出检测结果 | 出现 dect: 后跟检测结果列表 |
只有 FPS 或没有检测结果,说明当前画面没有有效目标 |
| FPS 显示 | 左上角显示当前帧率 | 帧率过低时减少串口打印或优化模型与分辨率 |
软件代码
本实验的软件部分以 4.9_mask_detection.py 为核心。程序导入 sensor、image、time、lcd、KPU 和 gc,完成 LCD 初始化、摄像头初始化、模型加载、YOLO2 初始化、图像采集、KPU 推理、检测结果绘制和内存回收。
| 软件环境 | 作用 | 检查重点 |
|---|---|---|
| CanMV IDE | 编辑、运行和调试 K210 程序 | 能识别开发板串口,并能运行基础摄像头示例 |
| CanMV 固件 | 提供 sensor、image、lcd、maix.KPU 等模块 |
固件环境需要支持 KPU 推理接口 |
| SD 卡 | 保存模型文件 | /sd/detect_5.kmodel 需要存在且文件名一致 |
| 摄像头驱动环境 | 图像采集基础 | sensor.reset() 不应报错 |
| LCD 显示环境 | 显示识别结果 | lcd.init() 和 lcd.display(img) 能正常工作 |
| 串口终端 | 查看模型加载、检测结果和调试输出 | 能看到 ready load model、dect: 或 FPS 相关信息 |
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----湖南创乐博智能科技有限公司----
# 文件名:4.9_mask_detection.py
# 版本:V2.0
# author: zhulin
# 说明:CanMv K210 Yolo口罩识别实验
#####################################################
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.156250, 0.222548, 0.361328, 0.489583, 0.781250, 0.983133, 1.621094, 1.964286, 3.574219, 3.94000)
# 创建一个kpu对象,用于人脸检测
kpu = KPU()
print("ready load model")
# 加载模型
kpu.load_kmodel("/sd/detect_5.kmodel")
# yolo2初始化
kpu.init_yolo2(anchor, anchor_num=5, img_w=320, img_h=240, net_w=320 , net_h=256 ,layer_w=10 ,layer_h=8, threshold=0.7, nms_value=0.4, classes=2)
while True:
#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 :
if l[4] :
a = img.draw_rectangle(l[0],l[1],l[2],l[3], color=(0, 255, 0))
a = img.draw_string(l[0],l[1]-24, "with mask", color=(0, 255, 0), scale=2)
else:
a = img.draw_rectangle(l[0],l[1],l[2],l[3], color=(255, 0, 0))
a = img.draw_string(l[0],l[1]-24, "without mask", color=(255, 0, 0), scale=2)
a = img.draw_string(0, 0, "%2.1ffps" %(fps), color=(0, 60, 128), scale=2.0)
lcd.display(img)
gc.collect()
# 创建的kpu对象去初始化,释放模型内存
kpu.deinit()
这段程序可以分成四个层级。初始化层负责启动 LCD、摄像头和 KPU;模型配置层负责加载 detect_5.kmodel 并设置 YOLO2 参数;推理层负责把摄像头图像转换成 AI 输入格式,并调用 KPU 运行模型;显示层负责根据检测结果绘制矩形框、类别文字和 FPS 信息。
od_img 是本实验中容易忽略的对象。摄像头采集到的是 320×240 的 QVGA 图像,但模型输入需要 320×256 的图像缓存,因此代码先创建 od_img,再把 img 绘制到 od_img 上,并通过 pix_to_ai() 转换成 KPU 推理需要的数据格式。这个步骤是视觉模型部署中常见的输入适配过程。
| 语句 / 参数 | 功能 | 对应现象 |
|---|---|---|
lcd.init() |
初始化 LCD 显示屏 | 屏幕准备显示摄像头画面 |
sensor.reset() |
初始化摄像头 | 摄像头开始采集准备 |
sensor.set_pixformat(sensor.RGB565) |
设置彩色图像格式 | LCD 显示彩色画面 |
sensor.set_framesize(sensor.QVGA) |
设置 320×240 图像尺寸 | 提供适合检测和显示的输入画面 |
image.Image(size=(320,256)) |
创建 AI 输入图像缓存 | 适配模型需要的输入尺寸 |
kpu.load_kmodel("/sd/detect_5.kmodel") |
加载模型文件 | 模型加载成功后进入推理流程 |
kpu.init_yolo2(...) |
初始化 YOLO2 后处理参数 | 设置 anchor、阈值、NMS 和类别数量 |
od_img.pix_to_ai() |
转换 AI 输入格式 | 图像可以送入 KPU 运算 |
kpu.run_with_output(od_img) |
执行模型推理 | KPU 对当前图像进行口罩检测 |
kpu.regionlayer_yolo2() |
获取 YOLO2 后处理结果 | 返回检测框和类别信息 |
img.draw_rectangle() |
绘制检测框 | 屏幕上出现红色或绿色矩形框 |
img.draw_string() |
绘制类别文字和 FPS | 屏幕显示 with mask、without mask 和帧率 |
gc.collect() |
回收内存 | 降低长时间运行时的内存压力 |
需要注意的是,代码最后的 kpu.deinit() 位于无限循环之后,正常运行时不会执行到这一行。它表达的是释放模型资源的意图,但当前程序没有跳出 while True 的逻辑。如果后续需要按键退出或异常退出后释放资源,可以在程序中增加退出条件,再执行 kpu.deinit()。
扩展应用
YOLO 口罩识别实验的调试重点集中在模型文件、摄像头画面、光照条件、目标距离、阈值设置和内存状态。出现问题时,应先确认摄像头能正常显示,再确认模型文件能够加载,最后再调整识别阈值和测试环境。
| 问题现象 | 可能原因 | 处理思路 |
|---|---|---|
| 程序无法运行 | 文件没有传到开发板、固件不支持相关模块、库文件缺失 | 确认主程序能运行,检查 CanMV 固件版本和报错行号 |
| 模型加载失败 | /sd/detect_5.kmodel 不存在、文件名不一致、SD 卡未识别 |
把模型文件复制到 /sd/,并核对 load_kmodel() 中的路径 |
| LCD 没有画面 | 摄像头排线松动、LCD 初始化异常、程序未进入主循环 | 先运行基础摄像头显示程序,确认摄像头和 LCD 正常 |
| 串口没有检测输出 | 当前画面没有识别到目标,或识别置信度不足 | 让人脸完整进入画面,调整距离和光照 |
| 佩戴状态识别错误 | 模型效果受角度、遮挡、光照、距离影响 | 固定摄像头和人脸位置,改善光照,减少侧脸和模糊画面 |
| 检测不到目标 | threshold=0.7 偏高、目标太小、画面模糊 |
适当降低阈值,靠近摄像头,保证人脸清晰 |
| 检测框位置偏移 | 模型输入尺寸、图像复制或显示比例造成偏差 | 检查 od_img 尺寸、img_w/img_h 和 net_w/net_h 配置 |
| FPS 较低 | KPU 推理、绘制、串口打印和内存回收都会消耗时间 | 减少无关打印,保持合适分辨率,避免同时运行过多功能 |
| 长时间运行后异常 | 内存碎片或资源未释放 | 保留 gc.collect(),减少临时对象创建,必要时增加退出释放逻辑 |
YOLO 口罩识别实验的价值不只在于复现实验现象,更在于理解边缘 AI 识别项目的基本结构。摄像头采集画面,模型判断目标类别,程序再把识别结果转换成显示、提示、记录或控制动作。掌握这个流程后,可以继续扩展到更多基于 KPU 的视觉识别任务。
| 应用场景 | 实现思路 | 可扩展能力 |
|---|---|---|
| 口罩佩戴提示 | 检测到 without mask 时在屏幕上突出显示提示 |
可扩展蜂鸣器、LED 警示或语音提示 |
| 门禁辅助演示 | 识别到 with mask 后允许进入,识别到 without mask 时提示检查 |
可扩展继电器、舵机门禁或刷卡联动 |
| 公共场景检测演示 | 使用摄像头观察画面中的佩戴状态 | 可扩展为课程演示、展板项目或边缘 AI 展示 |
| AI 课程案例 | 用本实验讲解模型文件、KPU 推理、YOLO 后处理和类别显示 | 可延伸到人脸检测、物体检测和手势识别 |
| 智能相机 | 将识别结果直接叠加到实时画面中 | 可扩展拍照保存、串口上传或无线通信 |
| 设备状态联动 | 不同检测类别触发不同动作 | 可扩展蜂鸣器、LCD 菜单、日志记录和云端上传 |
| 模型部署教学 | 通过模型路径、输入尺寸和阈值参数讲解部署流程 | 可扩展模型替换、参数调优和多类别检测 |
从工程角度看,建议保持"采集、推理、后处理、显示、执行"的分层。摄像头采集负责提供图像,KPU 推理负责得到模型输出,YOLO 后处理负责生成检测框和类别结果,显示与控制逻辑负责反馈给用户。后续把屏幕显示替换成蜂鸣器报警、门禁控制、串口上传或网络通信时,不需要重写摄像头和模型推理部分,只需要在检测结果之后增加业务动作。
总结
本实验通过 CanMV K210 完成了 YOLO 口罩识别实验,核心内容包括 LCD 初始化、摄像头采集、KPU 模型加载、YOLO2 参数配置、AI 图像格式转换、模型推理、检测结果后处理、类别判断、检测框绘制和 FPS 显示。它展示了 K210 边缘 AI 项目中从图像输入到识别输出的一条完整链路。
YOLO 口罩识别实验适合作为 K210 AI 视觉课程中的综合案例。它比普通摄像头显示实验更进一步,因为程序不仅能显示画面,还能加载模型并判断目标类别。后续课程可以继续扩展人脸检测、物体识别、门禁提示、蜂鸣器报警、数据记录和网络上传等方向。只要理解摄像头采集、KPU 推理和结果显示之间的关系,更多 CanMV K210 AI 项目都可以沿着同一套思路继续搭建。