# YOLOv5-for-3516
**Repository Path**: TaiZi0007/yolov5-for-3516
## Basic Information
- **Project Name**: YOLOv5-for-3516
- **Description**: 本仓库专为嵌入式大赛中的海思赛道AI视觉项目设计。
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 4
- **Created**: 2025-09-29
- **Last Updated**: 2025-09-29
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
#### **1、下载仓库中的YOLOv5-6.0.rar并解压**:
\- 将解压后的文件夹命名为`YOLOv5-6.0`。
#### **2、模型训练环境配置**
##### windows端:
**2.1:安装Anaconda - 可根据教程(已安装请跳过):**
[ Anaconda安装(2024最新版)-CSDN博客](https://blog.csdn.net/m0_66047447/article/details/141110995?ops_request_misc=%7B%22request%5Fid%22%3A%22b1c6142279f5410c492b8ee68cdca25b%22%2C%22scm%22%3A%2220140713.130102334..%22%7D&request_id=b1c6142279f5410c492b8ee68cdca25b&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-141110995-null-null.142^v102^pc_search_result_base9&utm_term=anaconda安装&spm=1018.2226.3001.4187)
**2.2:创建环境**
- 按下Win+R,输入cmd打开终端。
- 创建并激活环境:
```bash
conda create -n yolov5 python=3.7
conda activate yolov5
```
**2.3:安装GPU版本的CUDA**
```bash
pip install torch==1.8.1+cu111 torchvision==0.9.1+cu111 torchaudio==0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
```
**2.4:使用 `cd` 命令移动至 YOLOv5-6.0 文件夹下,并安装 `requirements.txt` 中的依赖**
```bash
pip install -r requirements.txt
pip install onnx-simplifier==0.3.6
pip install -r requirements.txt #重新安装
pip install protobuf==3.20.3
```
注意:确保按照`requirements.txt`文件中的库进行安装,这些库是配套的。特别是`numpy`和`onnx`,请使用文件中指定的版本。
#### **3、训练模型**
- 按照以下步骤配置数据集并开始训练。
**3.1:配置数据集**
- 确保您的数据集符合YOLO格式,并将文件放置在`~/yolov5-6.0/dataset`目录下,具体文件结构如下:
- **文件夹结构**:
```
~/yolov5-6.0/dataset/person # 数据集根目录
├── train
│ ├── images
│ │ ├── image1.jpg
│ │ ├── image2.jpg
│ │ └── ...
│ └── labels
│ ├── image1.txt
│ ├── image2.txt
│ └── ...
└── valid
├── images
│ ├── image1.jpg
│ ├── image2.jpg
│ └── ...
└── labels
├── image1.txt
├── image2.txt
└── ...
```
- **标注文件格式**:
- 每个图像对应一个同名的`.txt`文件,放在`labels`目录下。
- 标注文件中的每一行表示一个对象,格式为:`class_id x_center y_center width height`,其中坐标是归一化的值(0到1之间)。
- **创建YAML文件**:
- 创建一个YAML文件(例如
```
your_dataset.yaml #“your_dataset”是自主命名的,本案例中将其命名为person.yaml
```
),配置数据集路径和类别信息。示例如下:
```yaml
path: ./dataset/person # 数据集根目录
train: train/images # 训练图像路径
val: valid/images # 验证图像路径
nc: 2 # 类别数量
names: # 类别名称
0: Person
1: Other
```
- **保存YAML文件**:
- 将上述内容保存为`your_dataset.yaml(person.yaml)`,并将其放置在`~/yolov5-6.0/dataset`目录下。
**3.2:修改模型配置文件**
- 使用PyCharm、VSCode或记事本等文本编辑器打开`yolov5-6.0/models`目录下的`yolov5s.yaml`文件,并进行以下修改(本RAR文件已包含修改后的版本):
```
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license
# Parameters
nc: 80 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
anchors:
- [10,13, 16,30, 33,23] # P3/8
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5 v6.0 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, C3, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 6, C3, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, C3, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 3, C3, [1024]],
[-1, 1, SPPF, [1024, 5]], # 9
]
# YOLOv5 v6.0 head
head:
[[-1, 1, Conv, [512, 1, 1]],
# [-1, 1, nn.Upsample, [None, 2, 'nearest']],
[ -1, -1, nn.ConvTranspose2d,[ 256, 256, 2, 2 ] ],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13
[-1, 1, Conv, [256, 1, 1]],
#[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[ -1, -1, nn.ConvTranspose2d,[ 128, 128, 2, 2 ] ],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 20 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 23 (P5/32-large)
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
```
**注意:这里主要是将上采样层替换为反卷积层,以适应HI3516平台。**
**3.3:训练模型**
- 在`yolov5-6.0`文件夹下右键并选择“用终端打开”,或者在CMD终端中使用`cd`命令切换到`yolov5-6.0`文件夹。
- 进入conda环境并训练模型:
```bash
conda activate yolov5
python train.py --data ./dataset/your_data/your_dataset.yaml --cfg ./models/yolov5s.yaml --epochs 600 --batch-size 16
如可直接执行:python train.py --data ./dataset/person/data.yaml --cfg ./models/yolov5s.yaml --epochs 600 --batch-size 16
```
- `--data`:指定数据集配置文件路径,这里使用的是3.1中制作的`your_dataset.yaml`文件。
- `--cfg`:指定模型配置文件路径,这里使用的是在3.2中修改的`models`目录下的`yolov5s.yaml`文件。
- `--epochs`:指定训练轮次,请根据自身的数据集进行调整。
- `--batch-size`:指定批量大小,请根据您的硬件资源和数据集大小进行调整。
- 训练完成后,您可以在`~/yolov5-6.0/runs/train`目录下找到最新的训练文件夹(例如`exp`、`exp1`等)。打开该文件夹中的`weights`子文件夹,即可看到模型参数文件`best.pt`。
- 重要:如果训练过程参数出现”Nan“,则是因为所用的显卡不支持混合精度运算(amp),在使用的时候需要把amp禁用掉,具体流程请在其他地方查询。
**3.4:pt->onnx**
- 注意:下文中的`exp`文件夹请指定为3.3训练生成的文件夹。
- 在`yolov5-6.0`文件夹下右键并选择“用终端打开”,或者在CMD终端中使用`cd`命令切换到`yolov5-6.0`文件夹。
- 进入conda环境并进行pt文件到onnx的转换。假设您的最佳模型文件是`best.pt`,您可以运行以下命令:
```bash
conda activate yolov5
python export.py --data ./dataset/person/data.yaml --weights ./runs/train/exp/weights/best.pt --batch 1 --img 640 640 --train --include onnx --opset 10
```
- `--data`:指定数据集配置文件路径,这里使用的是3.1中制作的`your_dataset.yaml`文件。
- `--weights`:指定要转换的PyTorch模型文件路径,这里是3.3中训练完成后生成的`best.pt`文件。
- 转换完成后,您可以在`./runs/train/exp/weights`目录下看到生成的ONNX文件,文件名为`best.onnx`。
- 简化onnx模型:
```bash
cd ./runs/train/exp/weights
python -m onnxsim best.onnx best-sim.onnx
```
- 简化完成后,您可以在`./runs/train/exp/weights`目录下看到生成的简化文件,文件名为`best-sim.onnx`。
**3.5:onnx神经网络层名称修改(重要)**
- 打开`yolov5-6.0`文件夹下的`onnx-change-name.py`文件,将`pre_model_path`指定为3.4生成的`best-sim.onnx`文件路径,将`post_model_path`指定为您自定义的处理后文件路径。在conda环境下运行`onnx-change-name.py`文件,生成更改名称后的文件`best-sim-processed.onnx`,该文件将用于下一步操作。
例如,在`onnx-change-name.py`文件中设置:
```python
pre_model_path = r"./runs/train/exp/weights/best-sim.onnx"
post_model_path = r"./runs/train/exp/weights/best-sim-processed.onnx"
```
运行脚本:
```bash
conda activate yolov5
python onnx-change-name.py
```
运行完成后,您可以在`./runs/train/exp/weights`目录下看到生成的文件`best-sim-processed.onnx`。该文件将用于下一步操作。
#### 4、模型格式转换:onnx-to-caffe
**4.1 搭建Linux环境(已完成可跳过)**
- 搭建Linux环境,根据以下流程完成至2.2.3部分:
https://gitee.com/HiSpark/HiSpark_NICU2023/blob/master/2.2%20Taurus%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md
**4.2 LInux配置caffe环境**
- 鉴于配置过程较为繁琐,博主直接提供了一个预配置好的Docker镜像,以便开发者可以直接使用(该docker的操作不需要加上sudo)。
- 123云盘下载链接:https://www.123912.com/s/iiMUVv-WqNLh
- 使用**MobaXterm**通过SSH连接到**4.1步骤**中搭建的Linux虚拟机,在**终端输入并运行**以下代码:
```bash
sudo apt install docker.io -y
```
- 根据4.1文档中2.24节的步骤4将刚才下载的docker文件导入Linux虚拟机中,并运行以下代码:
```bash
docker load < caffe_v1.1.tar
```
- 导入成功后,运行以下代码:
```bash
docker images
```
- 可观察到

- 启动docker编译环境
- 执行下面的命令,启动docker编译环境,其中**caffe**为自定义的docker的名字,**9a374bc87d59 **为我Ubuntu下docker的IMAGE ID,这里**请根据自己docker image ID的不同自行修改**。
- 运行以下代码:
```bash
docker run -itd --net=host --name caffe 9a374bc87d59 /bin/bash
```

**4.3 进入Docker编译环境**
**注意**:请熟练掌握以下几条命令。如果您的Ubuntu系统重启后需要再次启动Docker编译环境,请按照以下四个步骤进行操作:
- 在终端执行下面的命令,查看当前运⾏的docker实例状态
```
docker ps -a
```
- 在终端执行下面的命令,启动Docker环境
```
docker start caffe
```
- 在终端执行下面的命令,进⼊docker编译环境
```
docker exec -it caffe bash
```

- 启动Docker容器中的Samba服务,以实现Docker容器与Windows主机之间的文件共享
```
service smbd restart
```
**注意:如果您需要退出docker容器,请执行下面的命令**,如果您退出docker容器后,又想从Ubuntu环境进入docker容器,请执行上面的四条命令。
```
exit
```
- 在**docker**中执行下面的命令,查看docker的IP地址,本地docker的IP地址是 192.168.86.131
```
ifconfig
```
- 在文件资源管理器中,右键点击**”此电脑“**,然后选择**“映射网络驱动器”**。

- 输入 `\\\docker`,然后点击 ‘完成’(请根据本机Docker容器的实际IP地址进行填写)。
- **注意**:如果连接失败,请在Docker容器的终端中输入 `service smbd restart` 以重启Samba服务。
```
\\192.168.86.131\docker
```

- 这样,Docker的根目录就会在Windows的文件资源管理器中显示了,从而方便您在Windows和Docker之间进行文件共享。

**4.4 模型格式转换**
- 在Windows文件资源管理器中,进入路径 `~\home\caffe\yolov5_onnx2caffe`,并将步骤3.5中生成的 `best-sim-processed.onnx` 文件复制到该目录下。

- 同时,在Docker终端中,使用以下命令移动到该文件夹:
```sh
cd /home/caffe/yolov5_onnx2caffe/
```
然后,使用 `ls` 命令来查看目录内容,确保 `best-sim-processed.onnx` 文件已经存在。

- 在该目录下,使用 `vim` 命令编辑 `convertCaffe.py` 文件:
- 进入编辑模式:
- 按 `i` 键进入插入模式。
然后,移动到第150至152行,进行以下修改:
- 将 `onnx_path` 修改为导入的 `best-sim-processed.onnx` 文件的位置。
- 将 `prototxt_path` 修改为 `./自命名.prototxt`。
- 将 `caffemodel_path` 修改为 `./自命名.caffemodel`。
例如,修改后的代码可能如下所示:
保存并退出编辑模式:
- 按 `Esc` 键退出插入模式。
- 输入 `:wq!` 保存更改并退出 `vim`。
- 最后,在Docker终端中运行 `convertCaffe.py` 脚本:
```sh
python convertCaffe.py
```
等待几秒钟后,显示转换完成。
- 在终端的当前目录下使用 `ls` 命令,可以观察到生成了相应的Caffe格式文件。同时,在Windows资源管理器的对应目录下也可以看到这些文件。
- 保存生成的 `.prototxt` 和 `.caffemodel` 文件,这些文件将用于下一步操作。
#### 5、模型格式转换:caffe-to-wk
**5.1 安装并配置RuyiStudio**
- **按照以下文档中“5.5.1”步骤完成RuyiStudio工具的安装,本案例将Project name命名为yolov5,如图所示:**
https://gitee.com/HiSpark/HiSpark_NICU2023/blob/master/5.5%20%E9%99%84%E5%BD%95.md

- **在系统资源管理器中打开项目文件夹**:
- 在RuyiStudio中,鼠标右击 `yolov5` 文件夹。
- 选择“Show In System Explorer”(在系统资源管理器中显示)。
- 在文件资源管理器中进入 `yolov5` 文件夹。


- **相关配置**
- 在 `yolov5` 目录下创建 `images` 和 `models` 文件夹。
- 在 `images` 文件夹下放入几张 JPG 格式的图片。

- 将 4.4 中生成的 `.prototxt` 和 `.caffemodel` 文件放入 `models` 文件夹下。

**5.2 配置 `yolov5.cfg` 文件**
- **返回RuyiStudio**:
- 打开RuyiStudio。
- **打开并配置 `yolov5.cfg` 文件**:
- 在RuyiStudio中,点击 `yolov5` 目录下的 `yolov5.cfg` 文件。
- 配置 `prototxt` 和 `caffemodel` 文件的地址:
- 通过 `prototxt` 的“Browse”键选择 `models` 文件夹下的 `自命名.prototxt`。
- 通过 `caffemodel` 的“Browse”键选择 `models` 文件夹下的 `自命名.caffemodel`。
- 如图所示:
- 等待一段时间后弹出 **images** 配置,点击 `images_list` 的 **“Create” **按钮

- 在文件选择对话框中,选择 `images` 文件夹下的多张 JPG 图片,并点击“打开”,系统会在 `images` 文件夹下自动生成相应的 `imageList.txt`并且在RuyiStudio 中完成`images_list`的配置。

- **修改mark_prototxt文件**:
- **注意**:RuyiStudio 预生成 wk 文件的 prototxt 神经网络层文件是 `mark_prototxt`,`mark_prototxt` 是由上一步骤中导入的 `自命名.prototxt` 生成的。
- **注意**:未修改的 `mark_prototxt` 的模型神经网络层与 `caffemodel` 模型参数是不匹配的,需要将 `mark_prototxt` 修改成与 `caffemodel` 匹配的格式。错误示范:

- 打开 `marker_prototxt` 配置中文件名对应的 `.prototxt` 文件。

- 删除掉文件末尾的三个 `Transpose` 层(其他 YOLO 的 tiny 版本可能有两个输出,具体根据您的模型进行调整)。
- 修改后面的三个 `Reshape` 层:
- 第一个 `dim` 改为 `0`。
- 删除第五个 `dim`。
- 第四个 `dim` 改为 `dim` 的平方。
- 如图所示:
------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------

- 修改完成后,请按 `Ctrl+S` 保存 `marker_prototxt` 文件。
- 点击 RuyiStudio 中 `marked_prototxt` 的“check”按钮,显示配置成功。


- **配置其他信息**:
- 请按照以下内容进行相应的参数配置:

- 参数说明:
prototxt ----------------------------- 导入caffe模型的prototxt文件
caffemodel -------------------------- 导入caffe模型的caffemodel文件
net_type ---------------------------- 模型类别(图像都是CNN)
is_simulation ----------------------- 是否进行仿真(默认即可)
marked_prototxt --------------------- 预生成wk文件的prototxt文件 (需要进行修改)
output_wk_name ---------------------- 导出的wk文件的命名
complie_model ----------------------- 导出模型的精度
log_level --------------------------- 是否开启日志文件
align_bytes ------------------------- 模型组对齐方式(默认)
batch_num --------------------------- 处理图片的批次
sparse_rate ------------------------ FC参数稀疏化操作(默认)
image_type ------------------------- 输入模型的图像类型(与后处理有关)
RGB_order -------------------------- 输入模型图像的通道顺序
image_list ------------------------- 参考图片
norm_type -------------------------- 模型输入数据初始化
mean_file -------------------------- 均值文件(一般不用加)
- 注意:在3516DV300中,`image_type` 需要选择 `YVU420SP`。
**5.3 模型转换**
- 以上配置完成后,点击“Make WK”按钮,等待转换完成。

- 转换完成后,会在 `yolov5` 目录下生成对应的 **WK 文件**,该文件将用于下一步操作。

#### 6、模型部署(新Ubuntu镜像)
**6.1 系统镜像烧录:**
- 配置相关信息,完成以下全部操作(已完成可跳过):
https://gitee.com/HiSpark/HiSpark_NICU2023/blob/master/2.2%20Taurus%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md
- 烧录系统镜像,完成以下全部操作(已完成可跳过):
https://gitee.com/HiSpark/HiSpark_NICU2023/blob/master/3.2%20Taurus_HelloWorld.md
**6.2、案例示例(效果):**
- **准备 SD 卡**:
- 解压 `import.rar` 文件夹。
- 将除了“验证图片”和“说明”以外的文件及文件夹导入 SD 卡中。
- 将 SD 卡插入 3516 的接口。
- **说明**:
- 博主训练了 visdrone-2019 数据集的 YOLOv5s 模型,可以直接使用。
- **执行命令**:
打开3516终端并执行以下命令,确保所有必要的文件和库被正确复制到系统中:
```sh
# 挂载 SD 卡
mount -t vfat /dev/mmcblk1p1 /mnt
# 复制必要的文件
cp /mnt/libvb_server.so /usr/lib/
cp /mnt/libmpp_vbs.so /usr/lib/
cp /mnt/models /userdata/ -rf
cp /mnt/aac_file /userdata/ -rf
mkdir /userdata/lib/ -p
cp /mnt/libopencv_world.so.4.5.5 /userdata/lib/
ln -s /userdata/lib/libopencv_world.so.4.5.5 /userdata/lib/libopencv_world.so.405
ln -s /userdata/lib/libopencv_world.so.405 /userdata/lib/libopencv_world.so
cp /mnt/sample_ai.conf /userdata
cp /mnt/*.so /usr/lib/
cp /mnt/ohos_camera_ai_demo /userdata/
chmod 777 /userdata/ohos_camera_ai_demo
# 复制模型
cp /mnt/vis2019.wk /userdata/models/hand_classify/
```
- **运行程序**:
- 进入 `/userdata/` 目录并运行 `ohos_camera_ai_demo` 程序:
```sh
cd /userdata/
./ohos_camera_ai_demo 1
```
- **效果检验**:
- 摄像头运行后,可以在显示器上对“验证图片”中的图片进行模型效果检验。将这些图片放置在合适的位置,并通过摄像头查看检测结果。
**6.3 Vscode配置(一定要先完成 6.1):**
- 文件复制:
- 将 `code` 目录下的 `ai_infer_process.c` 和 `ai_infer_process.h` 复制到 Docker 容器内的 `/home/openharmony/sdk_linux/sample/taurus/ai_sample/ai_infer_process` 目录下。
- 将 `code` 目录下的 `yolov2_hand_detect.c`、`hand_classify.c` 和 `hand_classify.h` 复制到 Docker 容器内的 `/home/openharmony/sdk_linux/sample/taurus/ai_sample/scenario/hand_classify` 目录下。
- 将 `code` 目录下的 `sample_media_ai.c` 复制到 Docker 容器内的 `/home/openharmony/sdk_linux/sample/taurus/ai_sample/smp` 目录下。
**6.4 配置修改(重要):**
**6.4.1、模型文件路径**
- **文件**:`yolov2_hand_detect.c`
- **修改内容**:将 `MODEL_FILE_HAND` 修改为第五节生成的 `.wk` 文件在 3516 内的位置和名称。
- 示例:
```c
#define MODEL_FILE_HAND "/userdata/models/hand_classify/vis2019.wk" //vis2019.wk请替换成你的wk文件的名称
```
**6.4.2、类别名称**
- **文件**:`hand_classify.c`
- **修改内容**:根据自身的训练数据集的种类修改 `classnamee`,确保格式相同。(多了个e)
- 示例:
```c
const char* classnamee[11][20] = {
{"pedestrian"},
{"person"},
{"bicycle"},
{"car"},
{"van"},
{"truck"},
{"tricycle"},
{"awningtricycle"},
{"bus"},
{"motor"},
{"others"},
}; //11是种类的总个数
```
**6.4.3、最大类别数**
- **文件**:`ai_infer_process.c`
- **修改内容**:将 `MAX_CLASSES` 修改为训练数据集中类别的数目,确保与训练数据集一致,根据自身的训练数据集的种类修改 `classname`,确保格式相同。
- 示例:
```c
#define MAX_CLASSES 11 // 例如,如果你有 11 个类别
char classname[11][20] = {
{"pedestrian"},
{"person"},
{"bicycle"},
{"car"},
{"van"},
{"truck"},
{"tricycle"},
{"awningtricycle"},
{"bus"},
{"motor"},
{"others"},
};
```
**6.4.4、置信度阈值调整**
- **重点**:`float thred(int layer)` 和 `float thred2(int layer)` 函数用于设置小、中、大框的置信度阈值。请根据串口输出的 `score` 值进行调整,以优化检测效果。
- 解释:
- `thred(int layer)`:设置每个层的物体置信度阈值。如果物体置信度低于该阈值,则跳过该预测框。
- `thred2(int layer)`:设置每个层的总置信度阈值。如果总置信度(物体置信度 × 类别置信度)低于该阈值,则跳过该类别。
- 一般来说,由于模型训练的效果,小、中、大物体的置信度阈值应依次递增。这样可以更好地平衡不同尺度目标的检测精度和误检率。
- **小物体**:通常需要较低的置信度阈值,因为小物体的特征较少,检测难度较大。
- **中物体**:可以设置中等的置信度阈值,以平衡检测精度和误检率。
- **大物体**:可以设置较高的置信度阈值,因为大物体的特征较多,更容易被准确检测。
- 示例:
```c
float thred(int layer) {
if (layer == 0) return 0.34f; // 小物体层阈值
else if (layer == 1) return 0.35f; // 中物体层阈值
else return 0.40f; // 大物体层阈值
}
float thred2(int layer) {
if (layer == 0) return 0.34f;
else if (layer == 1) return 0.35f;
else return 0.40f;
}
```
**6.4.5、yolov5后处理函数优化 - 框**
- 重点:在文件 `ai_infer_process.c`的
```
static unsigned int yolov5__process(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, DetectObjInfo *resBuf, int *bbox_num)
```
函数中,调整以下参数:
- `limit_small`、`limit_middle`、`limit_large`:用于控制进入 NMS 前小、中、大框的最大个数。需要根据图像验证串口输出的大中小框个数进行调整。
- `max_bbox_num`:用于控制显示器最多显示多少个框。博主试过最大值为 20 左右,超过可能会导致内存溢出。如果需要更大的值,请优化内存管理代码,并注意内存溢出时重启机器。
- 解释:
- `limit_small`、`limit_middle`、`limit_large`:这些参数用于限制每个层的最大检测数量,避免过多的候选框进入 NMS 过程,从而提高效率。
- `max_bbox_num`:控制最终显示的边界框数量,避免显示过多的框导致内存溢出。
- 示例:
```c
static unsigned int yolov5__process(SAMPLE_SVP_NNIE_PARAM_S *pstNnieParam, DetectObjInfo *resBuf, int *bbox_num) {
// 其他代码...
// 调整这些参数
int limit_samll = 35; // 小目标的最大检测数量限制
int limit_middle = 20; // 中目标的最大检测数量限制
int limit_large = 5; // 大目标的最大检测数量限制
int max_bbox_num = 17; // 最终输出的最大边界框数量
// 其他代码...
}
```
**6.4.6、yolov5后处理函数优化 - IOU阈值**
- **重点**:`iou_threshold` 用于 NMS 的调整,影响最终显示框的数量。如果两个框的重叠程度大于 `iou_threshold`,则会删除置信度较低的框。
- 解释:`iou_threshold`:设置两个框的重叠程度阈值。如果两个框的重叠程度大于该阈值,则保留置信度较高的框,删除置信度较低的框。
- 示例:
```c
float iou_threshold = 0.5f; // 设置 IoU 阈值
nms_by_class(&bbox_list, resBuf, bbox_num, iou_threshold); // 调用 NMS 算法
```
**6.4.7、yolov5后处理函数优化 - 特定类别的置信度调整**
- **重点**:`if (cls_index == 5) total_conf *= 0.9` 的作用是降低某个类别的置信度。当某个类别的置信度一直很高而其他类别的置信度较低时可以使用。相反,也可以提升某些类别的置信度。其中 cls_index == 5 代表训练时yaml的第零个物体,==6代表第一个物体,以此类推。
- 解释:`if (cls_index == 5) total_conf *= 0.9`:降低特定类别的置信度,避免该类别的置信度过高导致误检。
- 示例:
```c
for (int cls_index = 5; cls_index < Para_mum; cls_index++) {
cls_conf = *(inferred_data_addr + anchor_index * feature_length * Para_mum + cls_index * feature_length + index) / 4096.0f;
cls_conf = sigmoid(cls_conf); // 使用 sigmoid 函数将类别置信度映射到 [0, 1]
total_conf = cls_conf * obj_conf; // 总置信度 = 物体置信度 × 类别置信度
// 对特定类别进行权重调整
if (cls_index == 5) {total_conf *= 0.9;};
// 如果总置信度低于阈值,则跳过该类别
if (total_conf < thred2(yolo_layer_index)) continue;
}
```
**6.4.8、优化总结:**
**`thred`、 `thred2`**、**`iou_threshold`**、**`limit_small`、`limit_middle`、`limit_large`**都是十分重要的参数,请根据串口输出内容进行对模型检测效果的优化。
额外说明:`for (int cls_index = 5; cls_index < Para_mum; cls_index++)`:从 5 开始是因为 0, 1, 2, 3 是坐标信息,4 是物体置信度信息,5 及之后是类别置信度信息。
**6.5、生成程序:**
**6.5.1、进入 Docker 容器**:
使用以下命令进入 Docker 容器:
```sh
docker exec -it openharmony bash
```
**6.5.2、编译程序**:
进入构建目录并执行清理和编译命令:
```sh
cd /home/openharmony/sdk_linux/sample/build
make ai_sample_clean && make ai_sample
```
**6.5.3、查看和复制输出文件**:
编译完成后,可以在 `/home/openharmony/sdk_linux/sample/output` 目录下找到生成的ohos_camera_ai_demo文件。同时,在文件资源管理器挂载后的相同位置也可以看到这些文件,保存该文件。
**6.6 效果验证(要求执行完 6.2 )**
**6.6.1、准备 SD 卡**:
- 将步骤 6.5 生成的 `ohos_camera_ai_demo` 文件和步骤 5.3 生成的 `.wk` 文件复制到 SD 卡中。
- 将 SD 卡插入 3516 的接口。
**6.6.2、挂载 SD 卡并复制文件**:
打开终端并执行以下命令,确保所有必要的文件被正确复制到系统中:
```sh
# 挂载 SD 卡
mount -t vfat /dev/mmcblk1p1 /mnt
# 复制手部分类模型文件
cp /mnt/vis2019.wk /userdata/models/hand_classify/
# 删除旧的 ohos_camera_ai_demo 文件(如果存在)
rm /userdata/ohos_camera_ai_demo
# 复制新的 ohos_camera_ai_demo 文件
cp /mnt/ohos_camera_ai_demo /userdata/
# 赋予 ohos_camera_ai_demo 文件执行权限
chmod 777 /userdata/ohos_camera_ai_demo
```
**6.6.3、运行程序**:
- 进入 `/userdata/` 目录并运行 `ohos_camera_ai_demo` 程序:
```sh
cd /userdata/
./ohos_camera_ai_demo 1
```
**6.6.4、效果检验**:
- 摄像头运行后,可以在显示器上对训练数据集中的测试图片进行检测效果检验。
**6.7 操作代码可以查看”说明“**