<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>笔记 &#8211; Antonio</title>
	<atom:link href="/category/%E7%AC%94%E8%AE%B0/feed/" rel="self" type="application/rss+xml" />
	<link>https://nstar.ltd</link>
	<description></description>
	<lastBuildDate>Sat, 21 Jun 2025 19:46:23 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>ESP32-OTA</title>
		<link>/esp32-ota/</link>
					<comments>/esp32-ota/#respond</comments>
		
		<dc:creator><![CDATA[Antonio]]></dc:creator>
		<pubDate>Sat, 21 Jun 2025 19:46:23 +0000</pubDate>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[ESP32]]></category>
		<category><![CDATA[单片机]]></category>
		<guid isPermaLink="false">http://antonioz.asia/?p=246</guid>

					<description><![CDATA[使用ESP-IDF开发，以例程hello_world、simple_ota_example为例。 编译hell [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>使用ESP-IDF开发，以例程hello_world、simple_ota_example为例。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>编译hello_world生成hello_world.bin文件备用，作为OTA升级文件</p>



<p>新建工程，采用示例simple_ota_example：</p>



<p>在SDK设置界面修改以下参数：</p>



<pre class="wp-block-code"><code>CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL .bin文件url(注意使用http://)
CONFIG_EXAMPLE_WIFI_SSID            WIFI名称
CONFIG_EXAMPLE_WIFI_PASSWORD        WIFI密码
CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS 配置是否采用HTTPS，HTTPS需要LTS证书（暂不采用）</code></pre>



<p>修改完成后，构建工程</p>



<p>在cmd命令行（或anaconda命令行中）中输入</p>



<pre class="wp-block-code"><code>python -m http.server 8070</code></pre>



<p>打开HTTP服务</p>



<p>烧录程序到ESP32，观察串口输出，结果为hello_world例程输出结果。</p>
]]></content:encoded>
					
					<wfw:commentRss>/esp32-ota/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>STM32CubeIDE使用</title>
		<link>/stm32cubeide%e4%bd%bf%e7%94%a8/</link>
					<comments>/stm32cubeide%e4%bd%bf%e7%94%a8/#respond</comments>
		
		<dc:creator><![CDATA[Antonio]]></dc:creator>
		<pubDate>Fri, 20 Jun 2025 17:27:15 +0000</pubDate>
				<category><![CDATA[STM32]]></category>
		<guid isPermaLink="false">http://antonioz.asia/?p=239</guid>

					<description><![CDATA[新建工程： debug配置： 配置使用DAP作为调试器： 通过arm-eabi工具链以及openocd实现：包 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">新建工程：</h2>



<h3 class="wp-block-heading">debug配置：</h3>



<ul class="wp-block-list">
<li>System Wake-Up 勾选，用于低功耗时PA0实现唤醒</li>



<li>Timebase Source 默认选用SysTick，使用RTOS时，建议使用更加精确的 <strong>TIM</strong> 作为时钟源</li>
</ul>



<h3 class="wp-block-heading">配置使用DAP作为调试器：</h3>



<p>通过arm-eabi工具链以及openocd实现：<br>包括了&nbsp;<strong><a href="https://gnutoolchains.com/arm-eabi/">Windows Toolchain for ARM</a></strong>&nbsp;和&nbsp;<strong><a href="https://gnutoolchains.com/arm-eabi/openocd/">OpenOCD</a></strong>&nbsp;两个工具库</p>



<p>首先，需要调用&nbsp;<code>openocd.exe</code>&nbsp;开启一个连接到 DAP-Link 与目标微控制器的&nbsp;<a href="https://zhida.zhihu.com/search?content_id=218942787&amp;content_type=Article&amp;match_order=1&amp;q=GDB&amp;zd_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ6aGlkYV9zZXJ2ZXIiLCJleHAiOjE3NTA2MTI2NTksInEiOiJHREIiLCJ6aGlkYV9zb3VyY2UiOiJlbnRpdHkiLCJjb250ZW50X2lkIjoyMTg5NDI3ODcsImNvbnRlbnRfdHlwZSI6IkFydGljbGUiLCJtYXRjaF9vcmRlciI6MSwiemRfdG9rZW4iOm51bGx9.bVCu_8c0cDmqfIvQBsRCAyg_sVicztGfPWLQ_SYJjAo&amp;zhida_source=entity" target="_blank" rel="noreferrer noopener">GDB</a>&nbsp;调试服务；</p>



<p>然后，<strong>STM32CubeIDE</strong>&nbsp;就可以通过&nbsp;<code>arm-none-eabi-gdb.exe</code>&nbsp;访问这个 GDB 服务；</p>



<p>下载并且解压两个工具库之后，分别将它们的&nbsp;<code>bin</code>&nbsp;目录添加到操作系统的环境变量</p>



<h3 class="wp-block-heading" id="h_588638750_1">以命令行方式进行调用</h3>



<h3 class="wp-block-heading" id="h_588638750_2">配置 OpenOCD</h3>



<p>OpenOCD 命令的调用格式如下面的代码所示，其中的&nbsp;<code>-f</code>&nbsp;参数表示当前使用的是配置文件：</p>



<pre class="wp-block-code"><code>openocd.exe -f interface\调试器接口配置文件 -f target\目标微控制器配置文件</code></pre>



<p>调试器接口配置文件在&nbsp;<code>OpenOCD\share\openocd\scripts\interface</code>&nbsp;目录下，由于这里使用的是&nbsp;<strong>DAP-Link</strong>&nbsp;作为调试器，所以通常都是以&nbsp;<code>cmsis-dap.cfg</code>&nbsp;作为参数</p>



<p>目标微控制器配置文件在 <code>OpenOCD\share\openocd\scripts\target</code>&nbsp;目录下</p>



<p>以此为例：</p>



<pre class="wp-block-code"><code>openocd.exe -f interface\cmsis-dap.cfg -f target\stm32l0.cfg
openocd.exe -f interface\cmsis-dap.cfg -f target\stm32f1x.cfg
openocd.exe -f interface\cmsis-dap.cfg -f target\stm32f4x.cfg</code></pre>



<p>然后打开STM32cubeIDE调试配置，“虫子”图标</p>



<p>修改GDB配置为arm-none-eabi-gdb.exe</p>



<p>修改端口号为localhost:3333</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>/stm32cubeide%e4%bd%bf%e7%94%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Maixcam使用</title>
		<link>/maixcam%e4%bd%bf%e7%94%a8/</link>
					<comments>/maixcam%e4%bd%bf%e7%94%a8/#respond</comments>
		
		<dc:creator><![CDATA[Antonio]]></dc:creator>
		<pubDate>Sat, 15 Mar 2025 18:44:28 +0000</pubDate>
				<category><![CDATA[博客]]></category>
		<category><![CDATA[电子设计]]></category>
		<category><![CDATA[笔记]]></category>
		<guid isPermaLink="false">http://antonioz.asia/?p=218</guid>

					<description><![CDATA[Maixcam使用 注意： 模型转换时，分辨率需保持一致，若为640X640训练的模型，则后面onnx模型转换 [&#8230;]]]></description>
										<content:encoded><![CDATA[<h1>Maixcam使用</h1>
<h2>注意：</h2>
<ol>
<li>模型转换时，分辨率需保持一致，若为640X640训练的模型，则后面onnx模型转换为. cvimodel模型时需要保持参数一致！！！（适用于Maixcam的分辨率参数是320X224）</li>
<li>遇到如下问题，先升级ONNXRuntime—pip install &#8211;upgrade onnxruntime -i <a href="https://pypi.tuna.tsinghua.edu.cn/simple">https://pypi.tuna.tsinghua.edu.cn/simple</a></li>
</ol>
<p><img fetchpriority="high" decoding="async" class="alignnone size-full wp-image-219" src="/wp-content/uploads/2025/03/tpc-yolo_error.png" alt="" width="1232" height="136" srcset="/wp-content/uploads/2025/03/tpc-yolo_error.png 1232w, /wp-content/uploads/2025/03/tpc-yolo_error-300x33.png 300w, /wp-content/uploads/2025/03/tpc-yolo_error-1024x113.png 1024w, /wp-content/uploads/2025/03/tpc-yolo_error-768x85.png 768w" sizes="(max-width: 1232px) 100vw, 1232px" /></p>
<p>一般升级后错误消失</p>
<ol>
<li>在文件夹里放置的图片要求：<br />
1.是数据集集里面的<br />
2.大小必须一致<br />
3.边长一定是32的倍数。如果不是32的倍数，就一定不符合模型的输入张量。补救的方法是用python脚本给他填充成32的倍数也行</li>
</ol>
<hr />
<p>用于yolo11n-obb模型：</p>
<p>OBB是什么？——和普通的识别框相比，OBB的识别框可以随物体的姿态转动，更好地标识出物体！你运行Maixvision自带案例中的ai_vision/nn_yolo11n_obb.py试试，看看这框真帅吧！而下图是我自己训练的模型效果：</p>
<p><img decoding="async" src="https://maixhub.com/public/sharing/39207-b7887866d2d04d3bbf2f9bed5e41d8c0.png" alt="" /></p>
<p>有人会问：只看Maixpy官方文档的那个YOLO11-obb部署与识别教程可以吗？——可以，但是大概率会踩不少坑。你也许会遇到识别框无法旋转、INT8模型无法转换成功、运行模型后相机卡死、导入模型失败……等一系列烦人的事。所以，请将官方文档和我这篇文章结合起来食用效果更佳。</p>
<p>所用开发环境是Linux ubuntu22.04。若你是在Windows也没关系，其核心思想万变不离其宗。</p>
<p>如有更好的提议请告诉我，谢谢！</p>
<h1><strong>查看相机Maixpy版本</strong></h1>
<p>在相机内打开设置——设备信息，查看你的MaixPy版本。MaixPy不仅有电脑pip安装的，相机内部也有自己的MaixPy。要确保MaixPy是比较新的版本。</p>
<p>在Maixpy的github仓库中可以看到，自4.9.3开始才支持YOLO11-OBB检测（没找到YOLOV8-OBB是什么时候，所以最好用YOLO11来进行OBB检测）。如果你需要升级相机的maixpy版本，就要准备一个读卡器，烧录教程看maixcam官方文档的即可，很详细我这里就不说了。</p>
<h1><strong>采集数据集</strong></h1>
<p>大多数人常用相机里那个Maixhub客户端来在线设备采集，然而这种设备采集的曝光时间、增益值是自动的，如果你对数据集曝光要求比较严格，那就需要自己写个拍摄的程序。</p>
<p>例如我编写的是下面的采集程序。启动程序后，每秒拍摄4张图片储存在相机SD卡中。你可以随意修改它的曝光，设为-1代表自动。</p>
<pre><code class="language-python">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 &gt;= 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</code></pre>
<h1><strong>下载、配置yolo11训练工程</strong></h1>
<p>给它单独开一个conda环境，我用的python 3.10。</p>
<p>从<a href="https://github.com/ultralytics/ultralytics"><strong>https://github.com/ultralytics/ultralytics</strong></a>下载源码，不用选版本，直接下就行。下载好后执行 pip install -r ultralytics transformers -i <a href="https://pypi.tuna.tsinghua.edu.cn/simple。之后如果报错缺少XX包，你就pip安装什么包。另外注意pip包之间容易有版本冲突，所以不能无脑下载，而是应该提前去百度包和包、包和环境之间的版本对应关系">https://pypi.tuna.tsinghua.edu.cn/simple。之后如果报错缺少XX包，你就pip安装什么包。另外注意pip包之间容易有版本冲突，所以不能无脑下载，而是应该提前去百度包和包、包和环境之间的版本对应关系</a>。</p>
<h1><strong>准备数据集</strong></h1>
<p>（1）数据集文件介绍</p>
<p>制作好的数据集的文件夹分布是这样的：</p>
<p><img decoding="async" src="https://maixhub.com/public/sharing/39207-51430ef88f0f45dbaa17934b82118510.png" alt="" /></p>
<p>images/train 里面放训练图片，labels/train 里面放训练txt。</p>
<p>images/val 里面放验证图片，labels/val 里面放验证txt。</p>
<p>test里面可以是空的。</p>
<p>（2）txt格式介绍</p>
<p>用上海交通大学交龙战队开源的那个就行<a href="https://github.com/xinyang-go/LabelRoboMaster"><strong>https://github.com/xinyang-go/LabelRoboMaster</strong></a>，它生成的txt格式完全符合标准。标注的方法看它的readme。</p>
<blockquote><p>关于训练图片，最好是每张图片分辨率完全一样！！虽说理论上任何大小的图片都可以用于训练。但是训练的图片最好不要有的图片width过大、有的图片hight过大，因为之后训练的时候程序会给它们填充灰边使其统一大小。</p>
<p>（3）整理好的数据集放在哪都行，我习惯放在Ultralytics工程目录下。</p></blockquote>
<h1><strong>获取yolo11n-obb.pt文件</strong></h1>
<p>从这个链接可以下载所有的官方pt权重文件<a href="https://github.com/ultralytics/assets/releases"><strong>https://github.com/ultralytics/assets/releases</strong></a>。注意我们要的不是普通的yolo11n.pt，而是yolo11n-obb.pt ！！它俩结构不一样，只有后者用于检测旋转矩形。</p>
<blockquote><p>使用yolo11s-obb乃至其他字母的行吗？——我的建议是一定要基于yolo11n-obb进行训练。我曾经试过 s 的，但是一开始推理相机就卡死、掉线，必须重启，说明相机内存爆了！去官网查看pt文件的大小，n 文件大小为5MB，而 s 文件19MB体量太大，其他字母的更不用说了，一个比一个大根本不能用。</p></blockquote>
<h1><strong>必备的两个yaml（1）——路径与标签</strong></h1>
<p>在工程目录下创建myfile-obb.yaml，输入：</p>
<pre><code class="language-yaml">path: /home/wp/ultralytics-main/my_data# dataset root dirtrain: images/train
val: images/val
#test: images/testnames:
  0: apple</code></pre>
<p>简单解释一下：train和val是相对于path路径的。有个一劳永逸、安全但麻烦的方法是都使用绝对路径，当然我上面的代码可没有这样做。</p>
<p>这里我只写了一个类别。你可以随意更改类别的数目、内容。</p>
<h1><strong>必备的两个yaml（2）——网络定义</strong></h1>
<p>先声明一点：这个yaml是官方的，自己不用写，我们常说的“基于yolo…”就是选择的这个yaml。</p>
<p>在 ultralytics/cfg/models 下，你会看到从v3到v11所有版本的yaml，里面还细分了pose、obb、普通等各种模型，这个 yolo11-obb.yaml 就是我们想要的，复制一份放在工程目录下。</p>
<p><img decoding="async" src="https://maixhub.com/public/sharing/39207-cb168f32b0374401aee582e88ac3a738.png" alt="" /></p>
<blockquote><p>一定要重命名为yolo11n-obb.yaml，刚拿出来是不带s、n……这些字母的。</p></blockquote>
<p>内容只需要改标签类别(nc)这个数字。</p>
<p>网上有博主给你的，其网络结构大概率和官方的这个yaml内容一模一样，用vscode对比就能看出来。</p>
<h1><strong>编写训练器train.py</strong></h1>
<p>在工程目录下新建一个train.py，那个imgsz是缩放 / 填充预处理，如果你的图片小于这个数，就会填充黑边再训练。其余的改改路径就行：</p>
<p>而v8训练出来的模型识别框根本无法旋转，角度永远输出-1.0000。</p>
<p>可能出现的问题：明明我指定的是yolo11s的pt文件，但是训练前期非要给我下载yolo11n.pt</p>
<p>先说明一点——不要使用yolo11s训练。不过我们还是要解决这个问题：找到amp这个参数，将它关闭就行。在ultralytics-main官方文件中，amp参数在ultralytics/cfgdefault.yaml 中，以键值对的方式，默认为True，把它改为False就行了。</p>
<pre><code class="language-python">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()</code></pre>
<h1><strong>检查训练结果，获得pt模型文件</strong></h1>
<p>训练好之后，在 runs/obb 下就能看到检测结果了。</p>
<h1><strong>pt转ONNX</strong></h1>
<p>工程目录下新建transform.py，代码如下。</p>
<blockquote><p>这里的 width、height 一定要设置成32的倍数。如&gt;果你没有设置为32的倍数，程序会悄悄设置成32的倍数，之后可能不符合你的预期而浪费时间。</p></blockquote>
<p>转换成功后，在pt文件的同目录下就生成了。</p>
<pre><code class="language-python">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)</code></pre>
<h1><strong>ONNX转mud和cvimodel</strong></h1>
<p>（1）确定ONNX模型的输出节点</p>
<p>上https://netron.app/查看ONNX文件的结构图。按ctrl+F分别搜索：/model.23/dfl/conv/Conv_output_0，/model.23/Sigmoid_1_output_0，/model.23/Sigmoid_output_0。看看有没有这三个节点，如果缺少了说明模型错了。</p>
<p>（2）部署并配置算能的tpu-mlir</p>
<ul>
<li>先装好docker吧，用小鱼ROS命令装很轻松。终端输入：按照小鱼的指引一步步来就行。（Windows用其他方式安装）</li>
</ul>
<pre><code>wget http://fishros.com/install -O fishros &amp;&amp; . fishros</code></pre>
<ul>
<li>终端执行命令 wget <a href="https://sophon-file.sophon.cn/sophon-prod-s3/drive/24/06/14/12/sophgo-tpuc_dev-v3.2_191a433358ad.tar.gz">https://sophon-file.sophon.cn/sophon-prod-s3/drive/24/06/14/12/sophgo-tpuc_dev-v3.2_191a433358ad.tar.gz</a> 下载它的压缩包，下载好后执行docker load -i sophgo-tpuc_dev-v3.2_191a433358ad.tar.gz 。</li>
<li>在home目录下新建文件夹MaixCAM，在此文件夹下打开终端，执行 docker run &#8211;privileged &#8211;name MaixCAM -v $PWD:/workspace -it sophgo/tpuc_dev:v3.2 ，创建来一个MaixCAM的容器。没问题，然后关闭终端。</li>
<li>前往<a href="https://github.com/sophgo/tpu-mlir/releases"><strong>https://github.com/sophgo/tpu-mlir/releases</strong></a>，下载一个tpu_mlir-1.15b0-py3-none-any.whl，下载好后将它移动到MaixCAM，在文件夹内打开终端，输入 docker start MaixCAM &amp;&amp; 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的倍数。<img decoding="async" src="https://maixhub.com/public/sharing/39207-ae8cf0bd22674376a2335cb26bcf2ec2.png" alt="" />
<p><img decoding="async" src="https://maixhub.com/public/sharing/39207-930151844bee4c9483bf450f50792938.png" alt="" /></li>
</ul>
<blockquote><p>这里的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</p></blockquote>
<p>（4）建立转换脚本</p>
<p>新建 .sh 脚本，命名为convert_yolo11_to_cvimodel，里面输入下面的代码。</p>
<p>你需要修改的是：把net_name改成模型文件名字，宽和高改成模型输入口的大小。&#8211;output_names改成你自己的模型名称。</p>
<blockquote><p>可能出现的问题：在容器内报错：[ONNXRuntimeError] : 9 : NOT_IMPLEMENTED : Could not find an implementation for Reshape(19) node with name &#8216;/model.22/Reshape&#8217;</p>
<p>那就在容器内执行 pip install &#8211;upgrade onnxruntime -i <a href="https://pypi.tuna.tsinghua.edu.cn/simple">https://pypi.tuna.tsinghua.edu.cn/simple</a> 升级onnxruntime就行。</p></blockquote>
<pre><code>#!/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</code></pre>
<p>（5）生成cvimodel文件，制作mud文件</p>
<p>在容器中执行 chmod +x convert_yolo11_to_cvimodel.sh &amp;&amp; ./convert_yolo11_to_cvimodel.sh 命令。如果没问题的话，在 workspace 就能生成cvimodel文件。</p>
<p>有2种精度，选一种拷贝一份出来（更推荐使用INT8，虽然精度低，但是非常快），改名为my_model.cvimodel，再新建my_mud.mud文件，内容如下，改一下模型名称，改一下标签。</p>
<pre><code>[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</code></pre>
<p>很容易报如下图的错：这是因为文件夹中放置的用于INT8转换的图片不符合上述的3点要求，所以你再仔细检查检查。然而此时精度bf16的cvimodel文件已经输出了，你要是不用INT8，就可以不理会这个报错。</p>
<p><img decoding="async" src="https://maixhub.com/public/sharing/39207-89286b77c64146a19629eb3841124b8e.png" alt="" /></p>
<p>（6）模型导入MaixCAM，打包为软件</p>
<p>打开Maixvision，将相机连接。在文件管理器内，新建my_project文件夹，将cvimodel和mud文件同时导入。</p>
<p>在电脑上新建test.py输入下面的代码，Maixvision打开该文件然后运行。</p>
<pre><code class="language-python">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() &gt; 480 else 4, image.COLOR_RED, close=True)
# 打印识别框的信息print(obj)
    disp.show(img)</code></pre>
<p>如果报错“&#8217;maix._maix.nn.Object&#8217; object has no attribute &#8216;get_obb_points&#8217;”未找到get_obb_points这个函数，说明你相机内部的MaixPy版本低于4.9.3，一定要升级。</p>
]]></content:encoded>
					
					<wfw:commentRss>/maixcam%e4%bd%bf%e7%94%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>RTOS（计划中）</title>
		<link>/rtos%ef%bc%88%e8%ae%a1%e5%88%92%e4%b8%ad%ef%bc%89/</link>
					<comments>/rtos%ef%bc%88%e8%ae%a1%e5%88%92%e4%b8%ad%ef%bc%89/#respond</comments>
		
		<dc:creator><![CDATA[Antonio]]></dc:creator>
		<pubDate>Sun, 25 Aug 2024 13:59:51 +0000</pubDate>
				<category><![CDATA[博客]]></category>
		<category><![CDATA[笔记]]></category>
		<guid isPermaLink="false">http://9544061et3ky.vicp.fun/?p=92</guid>

					<description><![CDATA[实时操作系统： 概念：进程、线程、栈、堆、信号量、互斥量、互斥锁 RT-Thread 1.移植流程： 2.常用 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>实时操作系统：</p>



<p>概念：进程、线程、栈、堆、信号量、互斥量、互斥锁</p>



<h2 class="wp-block-heading">RT-Thread</h2>



<p>1.移植流程：</p>



<ul class="wp-block-list">
<li>下载RT-Thread源码</li>



<li>&#8230;</li>



<li></li>
</ul>



<p>2.常用函数</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>/rtos%ef%bc%88%e8%ae%a1%e5%88%92%e4%b8%ad%ef%bc%89/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>一些常用算法（LeetCode.面）</title>
		<link>/%e4%b8%80%e4%ba%9b%e5%b8%b8%e7%94%a8%e7%ae%97%e6%b3%95%ef%bc%88leetcode-%e9%9d%a2%ef%bc%89/</link>
					<comments>/%e4%b8%80%e4%ba%9b%e5%b8%b8%e7%94%a8%e7%ae%97%e6%b3%95%ef%bc%88leetcode-%e9%9d%a2%ef%bc%89/#respond</comments>
		
		<dc:creator><![CDATA[Antonio]]></dc:creator>
		<pubDate>Sat, 17 Aug 2024 15:12:35 +0000</pubDate>
				<category><![CDATA[博客]]></category>
		<category><![CDATA[笔记]]></category>
		<category><![CDATA[leetcode]]></category>
		<category><![CDATA[算法]]></category>
		<guid isPermaLink="false">http://192.168.1.8/?p=80</guid>

					<description><![CDATA[罗列一些常用算法（不定期更新）： 1.双指针-快慢指针 2.摩尔投票算法（求众数）]]></description>
										<content:encoded><![CDATA[
<p>罗列一些常用算法（不定期更新）：</p>



<ul class="wp-block-list">
<li>双指针-快慢指针</li>



<li>摩尔投票算法</li>
</ul>



<p>1.双指针-快慢指针</p>



<pre class="wp-block-code"><code>// 时间复杂度：O(n)
// 空间复杂度：O(1)
class Solution {
public:
int removeElement(vector&lt;int>&amp; nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex &lt; nums.size(); fastIndex++) {
if (val != nums&#91;fastIndex]) {
nums&#91;slowIndex++] = nums&#91;fastIndex];
 }
 }
return slowIndex;
 }
};</code></pre>



<p>2.摩尔投票算法（求众数）</p>



<pre class="wp-block-code"><code>// 摩尔投票算法
int majorityElement(int* nums, int numsSize) {
    int count = 0;
    int candidate = 0;

    for (int i = 0; i &lt; numsSize; i++) {
        if (count == 0) {
            candidate = nums&#91;i];
        }
        count += (nums&#91;i] == candidate) ? 1 : -1;
    }
    return candidate;
} </code></pre>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>/%e4%b8%80%e4%ba%9b%e5%b8%b8%e7%94%a8%e7%ae%97%e6%b3%95%ef%bc%88leetcode-%e9%9d%a2%ef%bc%89/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
