12浏览
查看: 12|回复: 4

[项目] 【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码

[复制链接]
什么是 CanMV K230?
CanMV 是一套 AI 视觉开发平台,K230 是其核心芯片。该模块结合了图像采集、AI推理、边缘计算等能力,适合嵌入式视觉应用开发。
CanMV:类似 OpenMV 的图像处理框架,支持 Python 编程,简化视觉识别开发流程。
K230 芯片:嘉楠科技推出的 AIoT SoC,采用 RISC-V 架构,内置第三代 KPU(AI加速单元),算力高达 6 TOPS,性能是 K210 的 13.7 倍。

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图2

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图1

驴友花雕  中级技神
 楼主|

发表于 3 小时前

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码

运行例程步骤
1. 打开CanMV IDE
双击运行我们安装好的CanMV IDE

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图1

点击区域 ② 打开串行终端

串行终端的作用是方便我们查看程序运行过程中的调试输出。开启或关闭串行终端不会影响到程序的运行效果

2. 将K230通过USB线连接至电脑
连接成功后,CanMV IDE 左下角的图标会发生变化

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图3

如果你没有开启【自动重新连接到CanMV】,则需要手动点击上面的按钮,等待CanMV IDE与K230建立连接

如果已开启自动连接,则等待几秒后,CanMV IDE 能成功的连接到 K230,左下角变成如图所示的样子

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图2

3. 运行例程代码
我们以人脸检测为例,打开我们下载的资料中【7.人脸识别 / 2.人脸检测】这个目录,找到face_detection.py

我们双击打开该文件

你可能看到的文件名是 face_detection,(没有.py)是因为你的电脑系统中没有设置显示文件扩展名

强烈建议在开发的过程中打开该选项,不同操作系统的开启方法都不相同,这里以win11为例

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图4

如果你没有设置过py后缀默认的打开文件,可以选择用系统自带的记事本软件打开代码

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图5

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图6

我们选中所有的代码,按下键盘上的 Ctrl + C 组合键,复制全部代码

然后回到CanMV IDE中,清空默认的内容后,按下Ctrl + V,粘贴我们刚刚复制下来的代码

CanMV IDE中新建一份文件会带有默认的一些代码内容,在粘贴之前请先全选并删除这些默认的代码

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图7

粘贴成功后,点击左下角绿色的运行按钮,K230将执行人脸检测功能

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图8

点击左下角红色按钮后,可以退出人脸检测功能

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图9

至此,我们就成功的使用 K230 在线运行了一个程序了。

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 3 小时前

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码

调试运行的人脸代码

  1. # 导入图像处理管线类和计时器工具类
  2. from libs.PipeLine import PipeLine, ScopedTiming
  3. # 导入 AI 模型基础类
  4. from libs.AIBase import AIBase
  5. # 导入图像预处理类
  6. from libs.AI2D import Ai2d
  7. # 导入系统和图像处理相关模块
  8. import os
  9. import ujson  # Micropython 下的 JSON 库
  10. from media.media import *  # 图像采集与显示相关函数
  11. from time import *  # 时间控制函数
  12. import nncase_runtime as nn  # K230 模型推理运行时库
  13. import ulab.numpy as np  # Micropython 下的轻量级 numpy 库
  14. import time
  15. import utime
  16. import image  # 图像处理模块
  17. import random
  18. import gc  # 垃圾回收模块
  19. import sys
  20. import aidemo  # AI 推理后处理模块(如人脸检测后处理)
  21. import _thread  # 多线程支持
  22. # 初始化串口通信模块
  23. from libs.YbProtocol import YbProtocol  # 自定义串口协议封装
  24. from ybUtils.YbUart import YbUart  # 串口通信类
  25. uart = YbUart(baudrate=115200)  # 创建串口对象,设置波特率为 115200
  26. pto = YbProtocol()  # 创建协议对象,用于封装串口发送的数据格式
  27. # 定义全局变量用于人脸检测实例
  28. face_det = None
  29. # 定义人脸检测应用类,继承自 AIBase,封装模型加载、预处理、推理、后处理、绘图等功能
  30. class FaceDetectionApp(AIBase):
  31.     def __init__(self, kmodel_path, model_input_size, anchors, confidence_threshold=0.5, nms_threshold=0.2, rgb888p_size=[224,224], display_size=[1920,1080], debug_mode=0):
  32.         super().__init__(kmodel_path, model_input_size, rgb888p_size, debug_mode)
  33.         self.kmodel_path = kmodel_path  # 模型路径
  34.         self.model_input_size = model_input_size  # 模型输入尺寸
  35.         self.confidence_threshold = confidence_threshold  # 检测置信度阈值
  36.         self.nms_threshold = nms_threshold  # 非极大值抑制阈值
  37.         self.anchors = anchors  # 锚框数据
  38.         self.rgb888p_size = [ALIGN_UP(rgb888p_size[0], 16), rgb888p_size[1]]  # 图像输入尺寸(宽度按 16 对齐)
  39.         self.display_size = [ALIGN_UP(display_size[0], 16), display_size[1]]  # 显示尺寸(宽度按 16 对齐)
  40.         self.debug_mode = debug_mode  # 调试模式标志
  41.         self.ai2d = Ai2d(debug_mode)  # 初始化图像预处理对象
  42.         self.ai2d.set_ai2d_dtype(nn.ai2d_format.NCHW_FMT, nn.ai2d_format.NCHW_FMT, np.uint8, np.uint8)  # 设置输入输出格式
  43.     def config_preprocess(self, input_image_size=None):
  44.         with ScopedTiming("set preprocess config", self.debug_mode > 0):
  45.             ai2d_input_size = input_image_size if input_image_size else self.rgb888p_size  # 获取输入尺寸
  46.             top, bottom, left, right = self.get_padding_param()  # 获取 padding 参数
  47.             self.ai2d.pad([0, 0, 0, 0, top, bottom, left, right], 0, [104, 117, 123])  # 设置边缘填充
  48.             self.ai2d.resize(nn.interp_method.tf_bilinear, nn.interp_mode.half_pixel)  # 设置插值方式
  49.             self.ai2d.build([1,3,ai2d_input_size[1],ai2d_input_size[0]], [1,3,self.model_input_size[1],self.model_input_size[0]])  # 构建预处理流程
  50.     def postprocess(self, results):
  51.         with ScopedTiming("postprocess", self.debug_mode > 0):
  52.             post_ret = aidemo.face_det_post_process(self.confidence_threshold, self.nms_threshold, self.model_input_size[1], self.anchors, self.rgb888p_size, results)  # 调用后处理函数
  53.             return post_ret[0] if post_ret else post_ret  # 返回检测结果
  54.     def draw_result(self, pl, dets):
  55.         with ScopedTiming("display_draw", self.debug_mode > 0):
  56.             if dets:
  57.                 pl.osd_img.clear()  # 清除上一帧绘制内容
  58.                 for det in dets:
  59.                     x, y, w, h = map(lambda x: int(round(x, 0)), det[:4])  # 获取检测框坐标
  60.                     x = x * self.display_size[0] // self.rgb888p_size[0]
  61.                     y = y * self.display_size[1] // self.rgb888p_size[1]
  62.                     w = w * self.display_size[0] // self.rgb888p_size[0]
  63.                     h = h * self.display_size[1] // self.rgb888p_size[1]
  64.                     pl.osd_img.draw_rectangle(x, y, w, h, color=(255, 255, 0, 255), thickness=2)  # 绘制黄色矩形框
  65.                     pto_data = pto.get_face_detect_data(x, y, w, h)  # 生成串口数据
  66.                     uart.send(pto_data)  # 发送串口数据
  67.                     print(pto_data)  # 打印数据
  68.             else:
  69.                 pl.osd_img.clear()  # 无检测结果时清屏
  70.     def get_padding_param(self):
  71.         dst_w = self.model_input_size[0]
  72.         dst_h = self.model_input_size[1]
  73.         ratio_w = dst_w / self.rgb888p_size[0]
  74.         ratio_h = dst_h / self.rgb888p_size[1]
  75.         ratio = min(ratio_w, ratio_h)
  76.         new_w = int(ratio * self.rgb888p_size[0])
  77.         new_h = int(ratio * self.rgb888p_size[1])
  78.         dw = (dst_w - new_w) / 2
  79.         dh = (dst_h - new_h) / 2
  80.         return (int(round(0)), int(round(dh * 2 + 0.1)), int(round(0)), int(round(dw * 2 - 0.1)))  # 返回 padding 参数
  81. # 主执行函数:加载模型、处理图像、显示结果
  82. def exce_demo(pl):
  83.     global face_det
  84.     display_mode = pl.display_mode  # 获取显示模式
  85.     rgb888p_size = pl.rgb888p_size  # 获取图像尺寸
  86.     display_size = pl.display_size  # 获取显示尺寸
  87.     kmodel_path = "/sdcard/kmodel/face_detection_320.kmodel"  # 模型路径
  88.     confidence_threshold = 0.5  # 置信度阈值
  89.     nms_threshold = 0.2  # 非极大值抑制阈值
  90.     anchor_len = 4200  # 锚框数量
  91.     det_dim = 4  # 检测框维度
  92.     anchors_path = "/sdcard/utils/prior_data_320.bin"  # 锚框数据路径
  93.     anchors = np.fromfile(anchors_path, dtype=np.float)  # 加载锚框数据
  94.     anchors = anchors.reshape((anchor_len, det_dim))  # 重塑锚框数据形状
  95.     try:
  96.         face_det = FaceDetectionApp(kmodel_path, model_input_size=[320, 320], anchors=anchors, confidence_threshold=confidence_threshold, nms_threshold=nms_threshold, rgb888p_size=rgb888p_size, display_size=display_size, debug_mode=0)  # 初始化人脸检测实例
  97.         face_det.config_preprocess()  # 配置图像预处理
  98.         while True:
  99.             with ScopedTiming("total",0):  # 总计时器
  100.                 img = pl.get_frame()  # 获取摄像头图像
  101.                 res = face_det.run(img)  # 执行人脸检测推理
  102.                 face_det.draw_result(pl, res)  # 绘制检测结果
  103.                 pl.show_image()  # 显示图像
  104.                 gc.collect()  # 垃圾回收
  105.                 time.sleep_us(10)  # 微秒级延时
  106.     except Exception as e:
  107.         print("人脸检测功能退出")  # 异常退出提示
  108.     finally:
  109.         face_det.deinit()  # 释放资源
  110. # 程序退出时释放资源
  111. def exit_demo():
  112.     global face_det
  113.     face_det.deinit()
  114. # 主程序入口
  115. if __name__ == "__main__":
  116.     rgb888p_size=[640,480]  # 设置图像尺寸
  117.     display_size=[640,480]  # 设置显示尺寸
  118.     display_mode
复制代码



相关代码解读

程序整体目标
该程序运行在 K230 AI视觉模块上,使用 Micropython 编写,主要功能是:
加载人脸检测模型(.kmodel)
采集摄像头图像并进行预处理
执行 AI 推理识别人脸
绘制检测框并通过串口发送识别结果
在 LCD 屏幕上实时显示处理后的图像

1. 模块导入与初始化
程序首先导入了多个模块:
AI 模型相关:AIBase, Ai2d, nncase_runtime
图像处理与显示:PipeLine, image, media
数据处理:ulab.numpy, ujson, gc, sys
串口通信:YbUart, YbProtocol
后处理逻辑:aidemo.face_det_post_process
并初始化了串口通信对象 uart 和协议封装对象 pto,用于将识别结果发送到外部设备。

2. FaceDetectionApp 类
这是程序的核心类,继承自 AIBase,封装了人脸检测的完整流程:
构造函数 __init__
加载模型路径、输入尺寸、锚框、置信度阈值等参数
初始化图像预处理模块 Ai2d
设置图像格式为 NCHW(适配模型输入)
方法 config_preprocess()
设置图像的 padding(边缘填充)和 resize(尺寸缩放)方式
构建预处理流程,将摄像头图像转换为模型输入格式
方法 postprocess(results)
使用 aidemo 库对模型输出进行后处理
提取人脸框坐标、置信度等信息
方法 draw_result(pl, dets)
将识别结果绘制到屏幕上
使用 draw_rectangle() 画出人脸框
通过串口发送识别数据(x, y, w, h)
方法 get_padding_param()
根据模型输入尺寸与原始图像尺寸计算缩放比例
自动生成 padding 参数,保证图像居中对齐

3. exce_demo(pl) 主执行函数
这是程序的主入口函数,执行以下步骤:
加载模型与锚框数据
从 TF 卡读取 .kmodel 和 .bin 文件
设置模型参数(输入尺寸、置信度、NMS 等)
初始化人脸检测实例
创建 FaceDetectionApp 对象
配置图像预处理流程
进入主循环
获取摄像头图像帧
执行模型推理
绘制识别结果
显示图像
进行垃圾回收与短暂延时

4. exit_demo()
程序退出时调用 face_det.deinit() 释放模型资源,避免内存泄漏。

5. 主程序入口
python
  1. if __name__ == "__main__":
复制代码

设置图像尺寸与显示模式(如 LCD)
创建图像处理管线 PipeLine
调用 exce_demo(pl) 启动人脸检测流程

程序执行流程图
plaintext
[摄像头图像] → [PipeLine 获取图像] → [AI2D 预处理] → [Kmodel 推理] → [后处理] → [绘制结果] → [显示图像 + 串口发送]


实验串口返回情况

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图1

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 3 小时前

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码

实际测试的几个范本

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图1

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图2

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图3

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图5

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图4
回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 3 小时前

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码

实验场景图  动态图

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图2

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图3

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图1

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图4

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图5

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图6

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图7

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图8

【花雕动手做】CanMV K230 AI视觉模块之调试运行人脸代码图9
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail