Maixcam使用

Maixcam使用

注意:

  1. 模型转换时,分辨率需保持一致,若为640X640训练的模型,则后面onnx模型转换为. cvimodel模型时需要保持参数一致!!!(适用于Maixcam的分辨率参数是320X224)
  2. 遇到如下问题,先升级ONNXRuntime—pip install –upgrade onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple

一般升级后错误消失

  1. 在文件夹里放置的图片要求:
    1.是数据集集里面的
    2.大小必须一致
    3.边长一定是32的倍数。如果不是32的倍数,就一定不符合模型的输入张量。补救的方法是用python脚本给他填充成32的倍数也行

用于yolo11n-obb模型:

OBB是什么?——和普通的识别框相比,OBB的识别框可以随物体的姿态转动,更好地标识出物体!你运行Maixvision自带案例中的ai_vision/nn_yolo11n_obb.py试试,看看这框真帅吧!而下图是我自己训练的模型效果:

有人会问:只看Maixpy官方文档的那个YOLO11-obb部署与识别教程可以吗?——可以,但是大概率会踩不少坑。你也许会遇到识别框无法旋转、INT8模型无法转换成功、运行模型后相机卡死、导入模型失败……等一系列烦人的事。所以,请将官方文档和我这篇文章结合起来食用效果更佳。

所用开发环境是Linux ubuntu22.04。若你是在Windows也没关系,其核心思想万变不离其宗。

如有更好的提议请告诉我,谢谢!

查看相机Maixpy版本

在相机内打开设置——设备信息,查看你的MaixPy版本。MaixPy不仅有电脑pip安装的,相机内部也有自己的MaixPy。要确保MaixPy是比较新的版本。

在Maixpy的github仓库中可以看到,自4.9.3开始才支持YOLO11-OBB检测(没找到YOLOV8-OBB是什么时候,所以最好用YOLO11来进行OBB检测)。如果你需要升级相机的maixpy版本,就要准备一个读卡器,烧录教程看maixcam官方文档的即可,很详细我这里就不说了。

采集数据集

大多数人常用相机里那个Maixhub客户端来在线设备采集,然而这种设备采集的曝光时间、增益值是自动的,如果你对数据集曝光要求比较严格,那就需要自己写个拍摄的程序。

例如我编写的是下面的采集程序。启动程序后,每秒拍摄4张图片储存在相机SD卡中。你可以随意修改它的曝光,设为-1代表自动。

from maix import camera, display, app, time
import os

# 设置摄像头分辨率
cam = camera.Camera(660, 280)
disp = display.Display()

cam.skip_frames(200)# 延时,等待相机稳定

exposure=cam.exposure(value = 3000)
gain=cam.gain(value = 3300)

# 保存文件夹路径。这是关于相机内的路径,和电脑路径无关
save_folder = "/root/photo"
if not os.path.exists(save_folder):
    os.makedirs(save_folder)

# 设置拍摄频率(每秒4张)
capture_interval = 0.25# 每张图片间隔时间
last_capture_time = time.time()

while not app.need_exit():
    img = cam.read()
    disp.show(img)# 显示图片

    current_time = time.time()
    if current_time - last_capture_time >= capture_interval:
# 生成文件名
        timestamp = int(current_time * 1000)# 使用时间戳作为文件名
        file_path = os.path.join(save_folder, f"{timestamp}.jpg")

# 保存图片
        img.save(file_path)
        print(f"Saved: {file_path}")

# 更新上次拍摄时间
        last_capture_time = current_time

    time.sleep(0.01)# 稍微延迟一下,避免占用过多CPU

下载、配置yolo11训练工程

给它单独开一个conda环境,我用的python 3.10。

https://github.com/ultralytics/ultralytics下载源码,不用选版本,直接下就行。下载好后执行 pip install -r ultralytics transformers -i https://pypi.tuna.tsinghua.edu.cn/simple。之后如果报错缺少XX包,你就pip安装什么包。另外注意pip包之间容易有版本冲突,所以不能无脑下载,而是应该提前去百度包和包、包和环境之间的版本对应关系

准备数据集

(1)数据集文件介绍

制作好的数据集的文件夹分布是这样的:

images/train 里面放训练图片,labels/train 里面放训练txt。

images/val 里面放验证图片,labels/val 里面放验证txt。

test里面可以是空的。

(2)txt格式介绍

用上海交通大学交龙战队开源的那个就行https://github.com/xinyang-go/LabelRoboMaster,它生成的txt格式完全符合标准。标注的方法看它的readme。

关于训练图片,最好是每张图片分辨率完全一样!!虽说理论上任何大小的图片都可以用于训练。但是训练的图片最好不要有的图片width过大、有的图片hight过大,因为之后训练的时候程序会给它们填充灰边使其统一大小。

(3)整理好的数据集放在哪都行,我习惯放在Ultralytics工程目录下。

获取yolo11n-obb.pt文件

从这个链接可以下载所有的官方pt权重文件https://github.com/ultralytics/assets/releases。注意我们要的不是普通的yolo11n.pt,而是yolo11n-obb.pt !!它俩结构不一样,只有后者用于检测旋转矩形。

使用yolo11s-obb乃至其他字母的行吗?——我的建议是一定要基于yolo11n-obb进行训练。我曾经试过 s 的,但是一开始推理相机就卡死、掉线,必须重启,说明相机内存爆了!去官网查看pt文件的大小,n 文件大小为5MB,而 s 文件19MB体量太大,其他字母的更不用说了,一个比一个大根本不能用。

必备的两个yaml(1)——路径与标签

在工程目录下创建myfile-obb.yaml,输入:

path: /home/wp/ultralytics-main/my_data# dataset root dirtrain: images/train
val: images/val
#test: images/testnames:
  0: apple

简单解释一下:train和val是相对于path路径的。有个一劳永逸、安全但麻烦的方法是都使用绝对路径,当然我上面的代码可没有这样做。

这里我只写了一个类别。你可以随意更改类别的数目、内容。

必备的两个yaml(2)——网络定义

先声明一点:这个yaml是官方的,自己不用写,我们常说的“基于yolo…”就是选择的这个yaml。

在 ultralytics/cfg/models 下,你会看到从v3到v11所有版本的yaml,里面还细分了pose、obb、普通等各种模型,这个 yolo11-obb.yaml 就是我们想要的,复制一份放在工程目录下。

一定要重命名为yolo11n-obb.yaml,刚拿出来是不带s、n……这些字母的。

内容只需要改标签类别(nc)这个数字。

网上有博主给你的,其网络结构大概率和官方的这个yaml内容一模一样,用vscode对比就能看出来。

编写训练器train.py

在工程目录下新建一个train.py,那个imgsz是缩放 / 填充预处理,如果你的图片小于这个数,就会填充黑边再训练。其余的改改路径就行:

而v8训练出来的模型识别框根本无法旋转,角度永远输出-1.0000。

可能出现的问题:明明我指定的是yolo11s的pt文件,但是训练前期非要给我下载yolo11n.pt

先说明一点——不要使用yolo11s训练。不过我们还是要解决这个问题:找到amp这个参数,将它关闭就行。在ultralytics-main官方文件中,amp参数在ultralytics/cfgdefault.yaml 中,以键值对的方式,默认为True,把它改为False就行了。

from ultralytics import YOLO

def main():
    model = YOLO('yolo11n-obb.yaml').load('/home/wp/ultralytics-main/yolo11n-obb.pt')# build from YAML and transfer weights
    model.train(data='myfile-obb.yaml', epochs=100, imgsz=416, batch=4, workers=4)
if __name__ == '__main__':
    main()

检查训练结果,获得pt模型文件

训练好之后,在 runs/obb 下就能看到检测结果了。

pt转ONNX

工程目录下新建transform.py,代码如下。

这里的 width、height 一定要设置成32的倍数。如>果你没有设置为32的倍数,程序会悄悄设置成32的倍数,之后可能不符合你的预期而浪费时间。

转换成功后,在pt文件的同目录下就生成了。

from ultralytics import YOLO

net_name = "/home/wp/ultralytics-main/runs/obb/train5/weights/best.pt"
input_width = 864# 一定是32的倍数
input_height = 288

model = YOLO(net_name)
path = model.export(format="onnx", imgsz=[input_height, input_width], dynamic=False, simplify=True, opset=17)# export the model to ONNX formatprint(path)

ONNX转mud和cvimodel

(1)确定ONNX模型的输出节点

上https://netron.app/查看ONNX文件的结构图。按ctrl+F分别搜索:/model.23/dfl/conv/Conv_output_0,/model.23/Sigmoid_1_output_0,/model.23/Sigmoid_output_0。看看有没有这三个节点,如果缺少了说明模型错了。

(2)部署并配置算能的tpu-mlir

  • 先装好docker吧,用小鱼ROS命令装很轻松。终端输入:按照小鱼的指引一步步来就行。(Windows用其他方式安装)
wget http://fishros.com/install -O fishros && . fishros
  • 终端执行命令 wget https://sophon-file.sophon.cn/sophon-prod-s3/drive/24/06/14/12/sophgo-tpuc_dev-v3.2_191a433358ad.tar.gz 下载它的压缩包,下载好后执行docker load -i sophgo-tpuc_dev-v3.2_191a433358ad.tar.gz 。
  • 在home目录下新建文件夹MaixCAM,在此文件夹下打开终端,执行 docker run –privileged –name MaixCAM -v $PWD:/workspace -it sophgo/tpuc_dev:v3.2 ,创建来一个MaixCAM的容器。没问题,然后关闭终端。
  • 前往https://github.com/sophgo/tpu-mlir/releases,下载一个tpu_mlir-1.15b0-py3-none-any.whl,下载好后将它移动到MaixCAM,在文件夹内打开终端,输入 docker start MaixCAM && docker attach MaixCAM 打开容器,执行 pip install tpu_mlir-1.15b0-py3-none-any.whl ,完成后如下图所示。(3)将你需要转换的onnx文件放到MaixCAM文件夹中,再将一些待会测试的图片放进去。这里注意,test.jpg和images文件夹里的所有图片有3点要求:1.这些图片来自于数据集。2.大小必须一致。补救的方法是用python脚本用(114,114,114)的灰色填充为大小一致。3.边长一定是32的倍数。如果不是32的倍数,就一定不符合模型的输入张量。补救的方法是用python脚本用(114,114,114)的灰色填充为32的倍数。

这里的test.jpg的作用是什么?用于程序内部预处理验证、模型测试。从数据集中选取一张与模型输入相同大小的图片即可。images里面的图像作用又是什么?你会发现这只是专为INT8的转换而传入的。因为模型从浮点类型转为int类型需要生成“校准表”,用来调整网络中各种阈值参数。这个过程可以看做小规模的数据集训练,最后得到程序所需的参数。你需要从训练集中尽可能挑选各种特色鲜明、非极端情况的图片100~1000张。详细原理看https://doc.sophgo.com/sdk-docs/v23.03.01/docs_latest_release/docs/tpu-mlir/developer_manual/html/07_calibration.html

(4)建立转换脚本

新建 .sh 脚本,命名为convert_yolo11_to_cvimodel,里面输入下面的代码。

你需要修改的是:把net_name改成模型文件名字,宽和高改成模型输入口的大小。–output_names改成你自己的模型名称。

可能出现的问题:在容器内报错:[ONNXRuntimeError] : 9 : NOT_IMPLEMENTED : Could not find an implementation for Reshape(19) node with name ‘/model.22/Reshape’

那就在容器内执行 pip install –upgrade onnxruntime -i https://pypi.tuna.tsinghua.edu.cn/simple 升级onnxruntime就行。

#!/bin/bash

set -e

net_name=my_obb
input_w=864
input_h=288

# mean: 0, 0, 0# std: 255, 255, 255# mean# 1/std# mean: 0, 0, 0# scale: 0.00392156862745098, 0.00392156862745098, 0.00392156862745098mkdir -p workspace
cd workspace

# convert to mlir
model_transform.py 
--model_name ${net_name} 
--model_def ../${net_name}.onnx 
--input_shapes [[1,3,${input_h},${input_w}]] 
--mean "0,0,0" 
--scale "0.00392156862745098,0.00392156862745098,0.00392156862745098" 
--keep_aspect_ratio 
--pixel_format rgb 
--channel_format nchw 
--output_names "/model.23/dfl/conv/Conv_output_0,/model.23/Sigmoid_1_output_0,/model.23/Sigmoid_output_0" 
--test_input ../test.jpg 
--test_result ${net_name}_top_outputs.npz 
--tolerance 0.99,0.99 
--mlir ${net_name}.mlir

# export bf16 model#   not use --quant_input, use float32 for easy coding
model_deploy.py 
--mlir ${net_name}.mlir 
--quantize BF16 
--processor cv181x 
--test_input ${net_name}_in_f32.npz 
--test_reference ${net_name}_top_outputs.npz 
--model ${net_name}_bf16.cvimodel

echo "calibrate for int8 model"
# export int8 model
run_calibration.py ${net_name}.mlir 
--dataset ../images 
--input_num 200 
-o ${net_name}_cali_table

echo "convert to int8 model"
# export int8 model#    add --quant_input, use int8 for faster processing in maix.nn.NN.forward_image
model_deploy.py 
--mlir ${net_name}.mlir 
--quantize INT8 
--quant_input 
--calibration_table ${net_name}_cali_table 
--processor cv181x 
--test_input ${net_name}_in_f32.npz 
--test_reference ${net_name}_top_outputs.npz 
--tolerance 0.9,0.6 
--model ${net_name}_int8.cvimodel

(5)生成cvimodel文件,制作mud文件

在容器中执行 chmod +x convert_yolo11_to_cvimodel.sh && ./convert_yolo11_to_cvimodel.sh 命令。如果没问题的话,在 workspace 就能生成cvimodel文件。

有2种精度,选一种拷贝一份出来(更推荐使用INT8,虽然精度低,但是非常快),改名为my_model.cvimodel,再新建my_mud.mud文件,内容如下,改一下模型名称,改一下标签。

[basic]
type = cvimodel
model = my_model.cvimodel

[extra]
model_type = yolo11
input_type = rgb
mean = 0, 0, 0
scale = 0.00392156862745098, 0.00392156862745098, 0.00392156862745098
labels = apple

很容易报如下图的错:这是因为文件夹中放置的用于INT8转换的图片不符合上述的3点要求,所以你再仔细检查检查。然而此时精度bf16的cvimodel文件已经输出了,你要是不用INT8,就可以不理会这个报错。

(6)模型导入MaixCAM,打包为软件

打开Maixvision,将相机连接。在文件管理器内,新建my_project文件夹,将cvimodel和mud文件同时导入。

在电脑上新建test.py输入下面的代码,Maixvision打开该文件然后运行。

from maix import camera, display, image, nn, app

detector = nn.YOLO11(model="/root/my_project/my_mud.mud", dual_buff = True)

cam = camera.Camera(detector.input_width(), detector.input_height(), detector.input_format())
disp = display.Display()

while not app.need_exit():
    img = cam.read()
    objs = detector.detect(img, conf_th = 0.7, iou_th = 0.65)# 阈值for obj in objs:

        points = obj.get_obb_points()
        msg = f'{detector.labels[obj.class_id]}: {obj.score:.2f}, {obj.angle * 180:.1f}'
        img.draw_string(points[0], points[1] - 4, msg, color = image.COLOR_RED)
        detector.draw_pose(img, points, 8 if detector.input_width() > 480 else 4, image.COLOR_RED, close=True)
# 打印识别框的信息print(obj)
    disp.show(img)

如果报错“’maix._maix.nn.Object’ object has no attribute ‘get_obb_points’”未找到get_obb_points这个函数,说明你相机内部的MaixPy版本低于4.9.3,一定要升级。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇