【Yolo 系列课】跟我学用 K230 实现图像检测

Viewed 85

问题描述


你是否想过,图像检测技术正以怎样的方式重塑我们的世界?从商场无人结算的 “秒级支付” 到医院 AI 辅助诊断的 “精准预判”,从工厂流水线上的 “毫米级质检” 到农田里的 “病虫害智能识别”,这项技术早已突破实验室的边界,渗透进我们生活的每一个角落。今天我们将以数字检测为例子,带领大家一步步完成图像检测在 K230 上的搭建。

image.png

一、训练环境准备

硬件:PC(考虑到训练需求,需要使用一台带 GPU 的电脑)
软件:Linux 操作系统/ Window 安装 WSL
网络:由于需要获取 github 的资源,最好是能够连接外网

1、搭建 YOLOv5 训练环境

git clone https://github.com/ultralytics/yolov5.git
cd yolov5
pip install -r requirements.txt

2、数据采集

我们已经提供 Micropython 脚本(请参考 K230 SDK 中代码 DataCollectionCamera.py),使用 K230 开发板就能完成数据采集的工作(数据采集脚本使用方法请参考文末 B站视频教程)

aaa@DESKTOP-OSN5BJK:~/canmv_k230_gitee_micropython$ cd src/canmv/resources/examples/16-AI-Cube/
aaa@DESKTOP-OSN5BJK:~/canmv_k230_gitee_micropython/src/canmv/resources/examples/16-AI-Cube$ ls
ClassificationApp.py  DataCollectionCamera.py  DetectionApp.py  MultiLabelApp.py  OCR_Det.py  SegmentationApp.py  SelfLearningApp.py

image.png

demo 运行起来如上图所示,我们在抓图的时候,尽量多角度,多距离抓取。

3、数据标注

图像识别的数据集,需要使用图片标注软件,在这里我们使用的是 labelme。
Labelme 下载链接:
https://github.com/wkentaro/labelme/releases/download/v5.5.0/Labelme.exe

image.png

tree -L 3 .
├── num_yolo 
│   ├── calc   //量化数据
│   ├── images //图片集合
│   │   ├── test //测试图片集
│   │   ├── train //训练图片集
│   │   └── val   //验证图片集
│   └── labels //标注框集合
│       ├── test
│       ├── train
│       └── val
└── num_yolo.yaml //训练时使用的配置文件

由于 labelme 标注出来的数据是 json 格式,我们需要使用脚本转换成 txt 格式的 label 数据。我们提供了一个转换的脚本,方便大家快速进行文本格式转换。

脚本下载地址:
https://kendryte-download.canaan-creative.com/developer/common/jsontotxt.py

二、模型训练

一切准备就绪,让模型开始学习!在 yolov5 目录下执行如下指令:

python train.py --weight yolov5n.pt --cfg models/yolov5n.yaml --data datasets/num_yolo.yaml --epochs 300 --batch-size 8 --imgsz 320 --device '0'

注意:这个命令的参数 --device '0' 是表示使用 GPU 资源训练,如果没有 GPU 的情况下,需要切换成 --device 'cpu'

训练完成显示如下(本地使用 CPU 电脑):

300 epochs completed in 1.611 hours.
Optimizer stripped from runs/train/exp2/weights/last.pt, 3.7MB
Optimizer stripped from runs/train/exp2/weights/best.pt, 3.7MB

Validating runs/train/exp2/weights/best.pt...
Fusing layers...
YOLOv5n summary: 157 layers, 1764577 parameters, 0 gradients, 4.1 GFLOPs
                 Class     Images  Instances          P          R      mAP50   mAP50-95: 100%|██████████| 3/3 [00:00<00:00,  4.83it/s]
                   all         41         41      0.993          1      0.995      0.928
                     0         41         11      0.992          1      0.995      0.957
                     1         41         10      0.995          1      0.995      0.872
                     2         41         10      0.993          1      0.995       0.93
                     3         41         10      0.993          1      0.995      0.953
Results saved to runs/train/exp2

三、模型转换

1、安装 nncase 和 onnx 转换工具

# linux平台/Linux虚拟机:nncase和nncase-kpu可以在线安装,nncase-2.x 需要安装 dotnet-7
sudo apt-get install -y dotnet-sdk-7.0
pip install --upgrade pip
pip install nncase==2.9.0
pip install nncase-kpu==2.9.0

# windows平台:请自行安装dotnet-7并添加环境变量,支持使用pip在线安装nncase,但是nncase-kpu库需要离线安装,在https://github.com/kendryte/nncase/releases下载nncase_kpu-2.*-py2.py3-none-win_amd64.whl# 进入对应的python环境,在nncase_kpu-2.*-py2.py3-none-win_amd64.whl下载目录下使用pip安装
pip install nncase_kpu-2.*-py2.py3-none-win_amd64.whl

# 除nncase和nncase-kpu外,脚本还用到的其他库包括:
pip install onnx
pip install onnxruntime
pip install onnxsim

2、下载转换脚本工具test_yolov5.zip并解压到yolov5目录下

wget https://kendryte-download.canaan-creative.com/developer/k230/yolo_files/test_yolov5.zip
unzip test_yolov5.zip

3、模型转换

按照指令先将训练好的pt模型导出为 onnx 模型,再转换为 kmodel 模型,以便在 K230 上运行,模型转换中需要使用 nncase 模型转换工具,请参考其使用指南:
https://www.kendryte.com/k230_rtos/zh/main/app_develop_guide/ai/nncase.html

量化数据集:我们在做模型转换的时候,需要使用训练数据的一个子集(推荐取训练数据的 20%)做量化,在模型转换的时候,需要指定到 --dataset 参数

# 导出onnx,pt模型路径请自行选择
python export.py --weight runs/train/exp2/weights/best.pt --imgsz 320 --batch 1 --include onnx
cd test_yolov5/detect
# 转换kmodel,onnx模型路径请自定义,生成的kmodel在onnx模型同级目录下
python to_kmodel.py --target k230 --model ../../runs/train/exp2/weights/best.onnx --dataset ../../datasets/num_yolo/images/calc --input_width 320 --input_height 320 --ptq_option 0
cd ../..

4、在文件下面,发现 kmodel 表示转换成功

aaa@DESKTOP-OSN5BJK:~/yolov5/yolov5$ find . -name *.kmodel
./runs/train/exp2/weights/best.kmodel

四、部署实战

1、准备开发环境

在 Canaan K230 开发板上部署模型,首先要烧录镜像并安装 CanMV IDE。按照开发板的下载链接获取镜像并烧录,再安装好 CanMV IDE。

镜像文件下载地址:
https://github.com/kendryte/canmv_k230/releases/tag/PreRelease

CanMV IDE下载地址:
https://www.kendryte.com/zh/resource/ide,k230

2、拷贝文件

连接 IDE ,把转换好的模型和测试图片拷贝到开发板目录下(路径可自定义,代码中记得同步修改)
image.png

3、代码实现推理

图片推理:编写代码从本地读取图片,并进行格式转换。通过 YOLOv5 类初始化实例,设置好任务类型、推理模式、模型路径、标签列表等参数。例如:

from libs.YOLO import YOLOv5
import os,sys,gc
import ulab.numpy as np
import image

# 从本地读入图片,并实现HWC转CHW
def read_img(img_path):
   img_data = image.Image(img_path)
   img_data_rgb888=img_data.to_rgb888()
   img_hwc=img_data_rgb888.to_numpy_ref()
   shape=img_hwc.shape
   img_tmp = img_hwc.reshape((shape[0] * shape[1], shape[2]))
   img_tmp_trans = img_tmp.transpose()
   img_res=img_tmp_trans.copy()
   img_return=img_res.reshape((shape[2],shape[0],shape[1]))
   return img_return,img_data_rgb888

if __name__=="__main__":
   img_path="/data/test.jpg"
   kmodel_path="/sdcard/examples/kmodel/best.kmodel"
   labels = ["0","1","2","3"]
   confidence_threshold = 0.5
   nms_threshold=0.45
   model_input_size=[320,320]
   img,img_ori=read_img(img_path)
   rgb888p_size=[img.shape[2],img.shape[1]]
   # 初始化YOLOv5实例
   yolo=YOLOv5(task_type="detect",mode="image",kmodel_path=kmodel_path,labels=labels,rgb888p_size=rgb888p_size,model_input_size=model_input_size,conf_thresh=confidence_threshold,nms_thresh=nms_threshold,max_boxes_num=50,debug_mode=0)
   yolo.config_preprocess()
   try:
       res=yolo.run(img)
       yolo.draw_result(res,img_ori)
       gc.collect()
   except Exception as e:
       sys.print_exception(e)
   finally:
       yolo.deinit()

运行代码,可以看到已经识别到这张图片上所有的数字并框出来了。

image.png

视频推理:视频推理更具挑战性。初始化 PipeLine 和 YOLOv5 实例,在循环中逐帧获取视频图像进行推理,实时展示识别结果。比如设置好显示模式、分辨率、模型路径等参数后,通过不断循环执行推理和显示操作:

from libs.PipeLine import PipeLine, ScopedTiming
from libs.YOLO import YOLOv5
import os,sys,gc
import ulab.numpy as np
import image

if __name__=="__main__":
    # 显示模式,默认"hdmi",可以选择"hdmi"和"lcd"
    display_mode="lcd"
    rgb888p_size=[800, 480]
    if display_mode=="hdmi":
        display_size=[1920,1080]
    else:
        display_size=[800,480]
    kmodel_path="/sdcard/examples/kmodel/best.kmodel"
    labels = ["0","1","2","3"]
    confidence_threshold = 0.8
    nms_threshold=0.45
    model_input_size=[320,320]
    # 初始化PipeLine
    pl=PipeLine(rgb888p_size=rgb888p_size,display_size=display_size,display_mode=display_mode)
    pl.create()
    # 初始化YOLOv5实例
    yolo=YOLOv5(task_type="detect",mode="video",kmodel_path=kmodel_path,labels=labels,rgb888p_size=rgb888p_size,model_input_size=model_input_size,display_size=display_size,conf_thresh=confidence_threshold,nms_thresh=nms_threshold,max_boxes_num=50,debug_mode=0)
    yolo.config_preprocess()
    try:
        while True:
            os.exitpoint()
            with ScopedTiming("total",1):
                # 逐帧推理
                img=pl.get_frame()
                res=yolo.run(img)
                yolo.draw_result(res,pl.osd_img)
                pl.show_image()
                gc.collect()
    except Exception as e:
        sys.print_exception(e)
    finally:
        yolo.deinit()
        pl.destroy()

这样,无论是静态图片还是动态视频中的数字,都能被精准识别。

通过 YOLOv5 和 Canaan K230 开发板实现数字识别,不仅是技术的有趣应用,也展示了人工智能在日常生活中的巨大潜力。感兴趣的小伙伴不妨动手试试,探索更多人工智能与实际应用结合的可能!

参考文档

官方资料:
https://www.kendryte.com/k230_canmv/zh/main/zh/example/ai/

Micropython AI手册:
https://www.kendryte.com/k230_canmv/zh/main/zh/api/aidemo_libs.html

视频教程:
https://www.bilibili.com/video/BV1xQ5YzoEW7

问答社区(增加标签YOLO):
https://www.kendryte.com/answer

1 Answers

来源: 勘智开发者微信公众号