- 2025-02-25
-
回复了主题帖:
嵌入式Rust修炼营:动手写串口烧录工具和MCU例程,Rust达人Hunter直播带你入门Rust
1.【参与理由&个人编程基础】
我常年从事嵌入式开发,具有丰富的仪器设备测试程序开发经验,具有光学专业研究背景,在实验室负责多种设备的远程控制和数据采集、相关应用项目的开发等,如MCU操控和Linux系统工控应用,在LabVIEW上位机控制、MATLAB数据编程、FORTRAN编程、科学计算求解非线性方程等方面具有扎实的理论基础以及丰富的实践经验。因此申请参与嵌入式 Rust 修炼营,深入学习这门先进的编程语言,紧跟时代发展,为之后的学习和科研工作提供参考。
2.【根据修炼任务和活动时间表,预估可以完成几级任务?】
高级。
3.【Rust学习过程遇到难点,希望在参与活动中收获什么?】
对Rust有一定了解,学习Rust过程的难点在于编程习惯不同,对于重要且常用的语法需要加强练习才能熟练掌握,因此希望参与此次活动,和大家共同学习、锻炼和分享 Rust 编程,并将其应用于实际项目的应用和开发中,和其他编程语言进行对比,以便针对具体问题获得更适合和更优秀的解决方案。
- 2025-02-22
-
回复了主题帖:
#AI挑战营(进阶)# 人脸识别部署
Jacktang 发表于 2025-2-22 15:06
幸狐 RV1106 开发板的人脸识别方案。部署的流程真不少
部署流程中的关键部分是环境搭建,之后根据幸狐官方提供的人脸识别例程,更换模型,再编译一下就能用了
- 2025-02-21
-
发表了主题帖:
#AI挑战营(进阶)# 人脸识别部署
# #AI挑战营(进阶)# 人脸识别部署
本文介绍了人脸识别方案在幸狐 RV1106 开发板的部署流程,作为之前帖子的补充,针对环境搭建、rknn 部署等关键部分进行细致分析描述,主要包括 Linux 操作系统部署、Conda 安装、ONNX 获取、RKNN 模型转化等,最后对测试效果进行展示和简要分析。
## RKNN-Toolkit2 安装
介绍了在 Windows 11 操作系统下的 rknn-toolkit2 工具的部署流程。
### Linux 系统安装
包括虚拟机安装与 Ubuntu 22.04 系统安装。
#### 虚拟机安装
[VMware Workstation 16.1.2 Pro for Windows](https://download3.vmware.com/software/wkst/file/VMware-workstation-full-16.1.2-17966106.exe)
密钥:`ZF3R0-FHED2-M80TY-8QYGC-NPKYF`
#### Ubuntu 系统
镜像文件下载:[Ubuntu 22.04](https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/22.04/) - ubuntu-22.04.5-desktop-amd64.iso
安装流程:[ubuntu安装教程 - CSDN](https://blog.csdn.net/qq_43374681/article/details/129248167)
1. 打开 VMware 软件,选择创建新的虚拟机;
2. 进入新建虚拟机向导,选择典型,选择 Ubuntu 镜像文件;
3. 定义占用磁盘空间,建议 100 G;
4. 自定义全名、用户名、密码;
5. 启动虚拟机,安装 Ubuntu 系统;
6. 选择目标语言等配置即可。
### Python 安装
Python 3.10 安装部署
运行 Terminal 终端命令行程序
```bash
sudo apt-get install python3.10
```
部署 rknn-toolkit2
```bash
git clone https://github.com/airockchip/rknn-toolkit2
```
> 若网速较慢,可通过 [网页](https://github.com/airockchip/rknn-toolkit2) 下载至本地。
安装 python 环境
```bash
sudo apt-get update
sudo apt-get install python3 python3-dev python3-pip
sudo apt-get install libxslt1-dev zlib1g zlib1g-dev libglib2.0-0 libsm6 libgl1-mesa-glx libprotobuf-dev gcc
```
安装 RKNN-ToolKit2 依赖包
```bash
cd home/ljl/Downloads/rknn-toolkit2-2.3.0
pip3 install -r rknn-toolkit2/packages/x86_64/requirements_cp310-2.3.0.txt
```
安装 RKNN-ToolKit2
```bash
pip3 install rknn-toolkit2/packages/x86_64/rknn_toolkit2-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
```
执行以下命令没有报错,则安装成功
```bash
python3
from rknn.api import RKNN
```
### Conda 安装
下载安装包
```bash
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-4.6.14-Linux-x86_64.sh
```
安装 miniconda
```bash
chmod 777 Miniconda3-4.6.14-Linux-x86_64.sh
bash Miniconda3-4.6.14-Linux-x86_64.sh
```
进入 Conda base 环境
```bash
source ~/miniconda3/bin/activate
```
#### 创建 RKNN-Toolkit2 Conda 环境
创建 RKNN-Toolkit2 开发 Conda 环境
```bash
conda create -n RKNN-Toolkit2 python=3.8
```
进入 RKNN-Toolkit2 Conda 环境
```bash
conda activate RKNN-Toolkit2
```
验证 Python 版本是否为 3.8
```bash
python --version
```
获取 RKNN-Toolkit2 安装包
```bash
git clone https://github.com/airockchip/rknn-toolkit2.git
```
进入文件夹
```bash
cd /home/ljl/miniconda3/envs/RKNN-Toolkit2/rknn-toolkit2-master
```
安装 RKNN-Toolkit2 相关的依赖库
```bash
pip install tf-estimator-nightly==2.8.0.dev2021122109
pip install -r rknn-toolkit2/packages/x86_64/requirements_cp38-2.3.0.txt -i https://pypi.mirrors.ustc.edu.cn/simple/
```
安装 RKNN-Toolkit2
```bash
pip install rknn-toolkit2/packages/x86_64/rknn_toolkit2-2.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
```
执行以下命令,验证是否安装成功
```bash
python
from rknn.api import RKNN
```
## ONNX 模型获取
ONNX 文件不仅储存了神经网络模型的权重,也储存了模型的结构信息以及网络中每一层的输入输出等信息。
根据模型的不同获取源码,人脸识别使用的模型训练推理源码与对应的 GitHub 地址如下
Retianface:https://github.com/bubbliiiing/retinaface-pytorch
### 人脸检测
人脸检测使用的模型为 retinaface,可以提取出人脸的边界框坐标、置信度和人脸五个特征点的坐标。通过人脸的边界框截取图像作为人脸特征提取的输入图像,可以提高人脸特征值获取的可靠性。
获取 retinaface 源码
```bash
git clone https://github.com/bubbliiiing/retinaface-pytorch.git
```
进入源码目录
```bash
cd /home/ljl/Downloads/retinaface-pytorch-master
```
搭建模型训练环境
```bash
conda create -n retinaface python=3.6
```
进入 Conda 虚拟环境并安装运行的依赖库
```bash
conda activate retinaface
pip install -r requirements.txt
```
在当前文件夹下创建导出 ONNX 文件的 python 脚本 `export_onnx.py`
```bash
touch export_onnx.py
vim export_onnx.py
```
粘贴如下代码
```python
from nets.retinaface import RetinaFace
from utils.config import cfg_mnet
import torch
model_path='model_data/Retinaface_mobilenet0.25.pth' #模型路径
model=RetinaFace(cfg=cfg_mnet,pretrained = False) #模型初始化
device = torch.device('cpu')
model.load_state_dict(torch.load(model_path,map_location=device),strict=False) #模型加载
net=model.eval()
example=torch.rand(1,3,640,640) #给定输入
torch.onnx.export(model,(example),'model_data/retinaface.onnx',verbose=True,opset_version=9) #导出
```
执行脚本获取 ONNX 文件(retinaface conda 环境下)
```bash
python export_onnx.py
```
在 `retinaface-pytorch-master/model_data` 文件夹下可得到转换后的 ONNX 文件
### 人脸特征提取
人脸特征提取可以根据输入的人脸图像提取出 128 维的特征值,可以与其他人脸的特征值计算欧氏距离来衡量匹配程度。
获取 facenet 源码
```bash
git clone https://github.com/bubbliiiing/facenet-pytorch.git
```
进入源码目录
```bash
cd /home/ljl/Downloads/facenet-pytorch-master
```
搭建模型训练环境
```bash
conda create -n facenet python=3.6
```
进入 Conda 虚拟环境并安装运行的依赖库
```bash
conda activate facenet
pip install -r requirements.txt
```
在当前 `facenet-pytorch-main` 文件夹下创建导出 ONNX 文件的 python 脚本 `export_onnx.py`
```python
from nets.facenet import Facenet
from torch import onnx
import torch
model_path='model_data/facenet_mobilenet.pth' #模型路径
model = Facenet(backbone="mobilenet",mode="predict",pretrained=True) #模型初始化
device = torch.device('cpu')
model.load_state_dict(torch.load(model_path, map_location=device), strict=False)
example=torch.rand(1,3,160,160) #给定一个输入
torch.onnx.export(model,example,'model_data/facenet.onnx',verbose=True,opset_version=9) #导出
```
执行脚本获取 ONNX 文件(facenet conda 环境下)
```bash
python export_onnx.py
```
在 `facenet-pytorch-main/model_data` 可以得到转换后的 ONNX 文件
使用 [Netron](https://netron.app/) 工具查看 ONNX 模型的结构
发现模型在输出前使用了 RKNPU 无法解析的 `ReduceL2` 算子,
需要注释路径 `facenet-pytorch/nets/facenet.py` 中的标准化操作
```python
def forward(self, x, mode = "predict"):
if mode == 'predict':
x = self.backbone(x)
x = self.avg(x)
x = x.view(x.size(0), -1)
x = self.Dropout(x)
x = self.Bottleneck(x)
x = self.last_bn(x)
#x = F.normalize(x, p=2, dim=1) #输出前的标准化
return x
x = self.backbone(x)
x = self.avg(x)
x = x.view(x.size(0), -1)
x = self.Dropout(x)
x = self.Bottleneck(x)
before_normalize = self.last_bn(x)
x = F.normalize(before_normalize, p=2, dim=1)
cls = self.classifier(before_normalize)
return x, cls
```
重新导出 ONNX 模型
## RKNN 模型转换
将 onnx 模型转化为 rknn 模型,以便部署于开发板。
### 模型转换
源码获取
```bash
git clone https://github.com/LuckfoxTECH/luckfox_pico_rknn_example.git
```
进入 `scripts/luckfox_onnx_to_rknn` 目录
```bash
cd luckfox_pico_rknn_example/scripts/luckfox_onnx_to_rknn
```
进入RKNN-Toolkit2 Conda 开发环境
```bash
conda activate RKNN-Toolkit2
```
模型转换
```bash
cd convert
python convert.py ../model/retinaface.onnx ../dataset/retinaface_dataset.txt ../model/retinaface.rknn Retinaface
```
生成开发板所需的 rknn 文件,
这里的转换代码定义为
```bash
python convert.py
```
### 模型验证
使用 [Netron](https://netron.app/) 工具解析输出的 rknn 模型,查看输入输出基本信息
> Luckfox-Pico 仅支持 `int8` 类型输入和输出
>
> Luckfox-Pico 仅支持 4 维输入维度和 4 维度输出维度
使用 Python 软件模拟器进行模型验证。
```python
from rknn.api import RKNN
rknn = RKNN()
rknn.config(mean_values=[[0, 0, 0]], std_values=[[128, 128, 128]],
target_platform='rv1103',
quantized_algorithm="normal")
rknn.load_onnx(model = model_path)
rknn.build(do_quantization=do_quant, dataset=DATASET_PATH)
rknn.init_runtime()
rknn.release()
```
### 编译运行
#### PC端编译
克隆或下载仓库
```bash
git clone https://github.com/LuckfoxTECH/luckfox_pico_rknn_example.git
```
设置环境变量
```bash
export LUCKFOX_SDK_PATH='/home/ljl/Downloads/luckfox_pico_rknn_example'
```
执行 `./build.sh`
```bash
chmod a+x ./build.sh
./build.sh
```
选择 `luckfox_pico_retinaface_facenet` 人脸识别例程
#### 板端运行
编译完成后,在 `luckfox_pico_rknn_example/install` 文件夹下生成对应的部署文件夹 `luckfox_pico_retinaface_facenet_demo`
使用 adb 方式将生成的部署文件夹完整上传到 Luckfox Pico 开发板
```bash
adb shell
mkdir HFR # 新建文件夹
exit
adb push D:\luckfox_pico_rknn_example\install\luckfox_pico_retinaface_facenet_demo /HFR
```
首先停止默认推流
```bash
adb shell
cd oem/usr/bin
RkLunch-stop.sh
```
进入开发板并执行
```bash
adb shell
cd HFR
chmod 777 luckfox_pico_retinaface_facenet_demo
cd luckfox_pico_retinaface_facenet_demo
./luckfox_pico_retinaface_facenet ./model/RetinaFace.rknn ./model/mobilefacenet.rknn ./model/test.jpg
```
通过 VLC media player 软件,依次进入媒体 - 打开网络串流 - 网络 - 输入URL
`rtsp://172.32.0.93/live/0`
点击 `播放`,即可实现 rtsp 推流显示。
### 效果
#### 单张人脸检测
##### 动态效果
#### 多张人脸检测
##### 动态效果
包括 rtsp 推流显示,人脸检测(动态方框)、特征提取、PowerShell命令端参数输出等内容。
#### 场景更换测试
更换测试图片,进行人脸检测
**动态效果**
同样包含人脸识别、图框提示、识别参数显示、终端参数连续输出等。
## 总结
本文介绍了人脸识别方案在幸狐 RV1106 开发板的部署流程,包括操作系统环境配置(虚拟机安装、Ubuntu 22.04 系统安装)、Conda 环境部署、RKNN-Toolkit2 工具安装部署、ONNX 模型获取、RKNN 模型转换、模型编译与上传、人脸识别效果检验等。步骤尽可能详细,为相关智能化需求应用场景(如门禁系统、安防、客流统计、考勤等)的开发提供了参考。
- 2025-02-20
-
回复了主题帖:
#AI挑战营第二站# 基于RKNN toolkit的模型转换与部署
Auralife 发表于 2025-1-15 10:39
有解决了吗
更换Ubuntu22.04和虚拟机就管用了
- 2025-02-12
-
回复了主题帖:
STC更名为Ai?这事你怎么看?
作为一名持续关注51单片机的电子爱好者,刚开始看到STC更名为Ai还有些一头雾水,转念想起了STC论坛的许多与人工智能相关的帖子,也就明白他们为啥改名了……
TinyML,Ai8051U 人工智能 开山之作,AI手写计算器 国芯技术交流网站 - AI32位8051交流社区
STC论坛有个专门的 AI 版块,里面有很多案例,如运行卷积神经网络、实现手写数字识别、手写计算器等,性能升级确实很厉害,甚至比肩32单片机,不得不令人刮目相看了,看来51单片机也是大有可图、未来可期啊~
- 2025-02-06
-
回复了主题帖:
【新年花灯秀】STM32F401RCT6 花样点灯
se7ens 发表于 2025-2-5 17:12
哇,传说中的彩色丝印PCB上线了
这种板的加工费要单独加钱不?
我用了¥50 彩色丝印券,批量生产的话需要和生产厂家详谈
- 2025-01-24
-
回复了主题帖:
新年新挑战,任务打卡赢好礼!
完善个人资料
回帖
课程学习
参与活动
资源下载
-
回复了主题帖:
#AI挑战营第二站# 基于RKNN toolkit的模型转换与部署
我安装的时候也遇到这种情况了,一直报错……
-
上传了资料:
STM32 自学笔记 - 蒙博宇
-
上传了资料:
51单片机实战指南 - 陈景波
- 2025-01-21
-
回复了主题帖:
【新年花灯秀】STM32F401RCT6 花样点灯
okhxyyo 发表于 2025-1-21 14:35
速度很快啊~~~第一个花灯点亮上线啦
哈哈,开发板上还有 OLED 屏接口,打算用来播放电子烟花
-
回复了主题帖:
【新年花灯秀】STM32F401RCT6 花样点灯
1084504793 发表于 2025-1-21 17:40 建议那几个字用LED灯显示,这样就更酷了。
建议不错,正在整活儿
用 WS2812 做个会闪烁的春联,嘿嘿
-
发表了主题帖:
【新年花灯秀】STM32F401RCT6 花样点灯
本帖最后由 lijinlei 于 2025-1-21 13:04 编辑
RGB 三色 LED 循环点亮
[localvideo]5076954fcfaef84c3c8f6658568e2422[/localvideo]
流水灯
[localvideo]cab4c9670847c7e0bcb20d4a9362648f[/localvideo]
RGB 灯代码
#include "main.h"
#include "gpio.h"
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, GPIO_PIN_SET);
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
流水灯代码
#include "main.h"
#include "gpio.h"
void SystemClock_Config(void);
int main(void)
{
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_3, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
HAL_Delay(100);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
}
/* USER CODE END 3 */
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
工程使用 STM32CubeMX 生成,根据开发板原理图,控制 GPIO 输出高低电平并延时。
该开发板由本人设计,主要特点是彩色丝印——蛇年赛博春联,主控为高性能 STM32F401RCT6 芯片,具有板载RGB LED以及多个用户自定义LED,便于实现多种闪烁效果; Flash 扩展和 IIC OLED 以及 TFT 屏等多功能接口,便于实现更多显示效果。
设计亮点
支持 FLASH 扩展;
支持用户按键、LED调控;
支持所有 GPIO 引脚外部连接;
支持电源供电扩展,便于更多外设供电;
支持 SWD 接口下载程序;
支持 1.8 寸 TFT 屏模块接口,配合彩色动态画面显示,使整个界面融为一体;
支持 IIC OLED 显示屏模块接口,配合温湿度传感器等,显示相关信息;
配合暖冬图片和半透明立体雪花效果,营造浓厚的冬季氛围;
春联包含辞旧迎新的美好祝愿,突出对中华传统文化和祖国壮丽河山的向往之情;
STM32F401RCT6 基于高性能 ARM®Cortex®-M4 32 位 RISC 核心,工作频率高达 84 MHz。
Cortex®-M4 核心具有浮点单元 (FPU) 单精度,支持所有 ARM 单精度数据处理指令和数据类型。它还实现了一套完整的 DSP 指令和内存保护单元 (MPU),增强了应用程序的安全性。
STM32F401RCT6 集成了高速嵌入式存储器 (256KB 闪存,64kKB SRAM),以及广泛的增强型 GPIO 和外设,连接到两个APB总线,两个 AHB 总线和一个 32 位多 AHB 总线矩阵。所有器件都提供一个 12 位 ADC,一个低功耗RTC,六个通用的 16 位定时器,包括一个用于电机控制的 PWM 定时器,两个通用的 32 位定时器。它们还具有标准和先进的通信接口。
STM32F401xB/STM32F401xC 在 - 40 至 + 125 °C 的温度范围内工作,电源电压为 1.7 (PDR OFF) 至 3.6 V。一套全面的省电模式允许设计低功耗应用。
这些特性使 STM32F401xB/STM32F401xC 微控制器适用于广泛的应用。
功能参数
带 BAM 的动态效率线(批量采集模式)
1.7 V 至 3.6 V 电源
温度范围:-40 °C 至 85/105/125 °C
内核:带 FPU 的 Arm 32 位 Cortex-M4 CPU、允许从闪存执行零等待状态的自适应实时加速器(ART 加速器™)、频率高达 84 MHz、内存保护单元、105 DMIPS/1.25 DMIPS/MHz (Dhrystone 2.1) 和 DSP 指令®®
记忆
高达 256 KB 的闪存
512 字节的 OTP 内存
高达 64 KB 的 SRAM
时钟、复位和电源管理
1.7 V 至 3.6 V 应用电源和 I/O
POR、PDR、PVD 和 BOR
4 至 26 MHz 晶体振荡器
内部 16 MHz 工厂调整 RC
用于 RTC 的 32 kHz 振荡器,带校准
带校准的内部 32 kHz RC
功耗
运行:128 μA/MHz(外设关闭)
停止(停止模式下的闪光灯,快速唤醒时间):42 μA 典型值 @ 25 °C;最大 65 μA @25 °C
停止(在深度掉电模式下闪烁,唤醒时间缓慢):在 25 °C typ@低至 10 μA;最大 28 μA @25 °C
待机:2.4 μA @25 °C / 1.7 V,无 RTC;12 μA @85 °C @1.7 V
V蝙蝠RTC 电源:1 μA @25 °C
1×12 位、2.4 MSPS 模数转换器:多达 16 个通道
通用 DMA:具有 FIFO 和突发支持的 16 流 DMA 控制器
多达 11 个定时器:多达 6 个 16 位定时器、2 个高达 84 MHz 的 32 位定时器,每个定时器具有多达 4 个 IC/OC/PWM 或脉冲计数器和正交(增量)编码器输入、两个看门狗定时器(独立和窗口)和一个 SysTick 定时器
调试模式
串行线调试 (SWD) 和 JTAG 接口
Cortex-M4 嵌入式跟踪宏单元™®
多达 81 个 I/O 端口,具有中断功能
所有 IO 端口均可承受 5 V 电压
多达 78 个高达 42 MHz 的快速 I/O
多达 11 个通信接口
最多 3 × I2C 接口(1Mbit/s,SMBus/PMBus)
最多 3 个 USART(2 x 10.5 Mbit/s、1 x 5.25 Mbit/s)、ISO 7816 接口、LIN、IrDA、调制解调器控制)
多达 4 个 SPI(f 时高达 42 Mbits/s)中央处理器= 84 MHz)、SPI2 和 SPI3,带多路复用全双工 I2S 通过内部音频 PLL 或外部时钟实现音频类精度
SDIO 接口
高级连接
具有片上 PHY 的 USB 2.0 全速器件/主机/OTG 控制器
CRC 计算单元
96 位唯一 ID
RTC:亚秒级精度、硬件日历
所有软件包均ECOPACK2
原理图
完整工程见附件。
- 2025-01-13
-
发表了主题帖:
# #AI挑战营(进阶)# 人脸识别
# #AI挑战营(进阶)# 人脸识别
利用 RKMPI 库实现摄像头图像捕获、预处理、硬件编码,结合 opencv-mobile 进行图像处理,可以将 RKNN 推理结果标注在图像上后作为作为流媒体服务器进行 rtsp 推流,在局域网下的 PC 可以使用 VLC 软件拉取并观察图像。
## 简介
介绍 InsightFace 数据库实现人脸识别的流程。
### InsightFace
[InsightFace](https://insightface.ai/) 是一个开源的 2D&3D 深度人脸分析工具箱,主要基于 PyTorch 和 MXNet。
主分支可与 **PyTorch 1.6+** 和/或 **MXNet=1.6-1.8** 以及 **Python 3.x** 配合使用。
InsightFace 有效地实施了各种先进的人脸识别、人脸检测和人脸对齐算法,这些算法针对训练和部署进行了优化。
InsightFace 提供了用于深度人脸识别的训练数据、网络设置和损失设计。
支持的方法如下:
- [ArcFace_mxnet](https://github.com/deepinsight/insightface/blob/master/recognition/arcface_mxnet)
- [ArcFace_torch](https://github.com/deepinsight/insightface/blob/master/recognition/arcface_torch)
- [ArcFace](https://github.com/deepinsight/insightface/blob/master/recognition/subcenter_arcface)
- [PartialFC_mxnet](https://github.com/deepinsight/insightface/blob/master/recognition/partial_fc)
- [PartialFC_torch](https://github.com/deepinsight/insightface/blob/master/recognition/arcface_torch)
- [VPL](https://github.com/deepinsight/insightface/blob/master/recognition/vpl)
- [Arcface_oneflow](https://github.com/deepinsight/insightface/blob/master/recognition/arcface_oneflow)
- [ArcFace_Paddle](https://github.com/deepinsight/insightface/blob/master/recognition/arcface_paddle)
最常用的网络骨干网都包含在大多数方法中,例如 IResNet、MobilefaceNet、MobileNet、InceptionResNet_v2、DenseNet 等。
训练数据包括且不限于 MS1M、VGG2 和 CASIA-Webface 数据集。
##### ArcFace 实现
- PyTorch:[InsightFace_Pytorch](https://github.com/TreB1eN/InsightFace_Pytorch)
- PyTorch:[arcface-pytorch](https://github.com/ronghuaiyang/arcface-pytorch)
[RetinaFace](https://github.com/deepinsight/insightface/blob/master/detection/retinaface) 是一款实用的单级人脸检测器,已被 [CVPR 2020](https://openaccess.thecvf.com/content_CVPR_2020/html/Deng_RetinaFace_Single-Shot_Multi-Level_Face_Localisation_in_the_Wild_CVPR_2020_paper.html) 接受。我们提供训练代码、训练数据集、预训练模型和评估脚本。
根据 InsightFace 的 Python 库模型,可进行人脸检测和识别
#### Python 示例
```python
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
app = FaceAnalysis(providers=['CUDAExecutionProvider', 'CPUExecutionProvider'])
app.prepare(ctx_id=0, det_size=(640, 640))
img = ins_get_image('t1')
faces = app.get(img)
rimg = app.draw_on(img, faces)
cv2.imwrite("./t1_output.jpg", rimg)
```
该示例实现了从图像中检测人脸并在其上绘制检测结果。
最新的 insightface 库仅支持 onnx 模型。使用 PyTorch、MXNet 或任何其他框架训练检测或识别模型后,可将其转换为 onnx 格式,然后使用 insightface 库进行调用。
##### 模型检测
```python
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
# Method-1, use FaceAnalysis
app = FaceAnalysis(allowed_modules=['detection']) # enable detection model only
app.prepare(ctx_id=0, det_size=(640, 640))
# Method-2, load model directly
detector = insightface.model_zoo.get_model('your_detection_model.onnx')
detector.prepare(ctx_id=0, input_size=(640, 640))
```
##### 模型识别
```python
import cv2
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image
handler = insightface.model_zoo.get_model('your_recognition_model.onnx')
handler.prepare(ctx_id=0)
```
#### 人脸对齐
提供了用于人脸对齐的数据集和训练/推理管道。
支持的方法:
- [SDUNet ](https://github.com/deepinsight/insightface/blob/master/alignment/heatmap) 是一种基于 [BMVC](http://bmvc2018.org/contents/papers/0051.pdf) 接受的基于热图的方法。
- [SimpleRegression (简单回归)](https://github.com/deepinsight/insightface/blob/master/alignment/coordinate_reg):提供了轻量级的面部特征点模型,具有快速的坐标回归功能。这些模型的输入是松散裁剪的人脸图像,而输出的是坐标。
### ArcFace
[ArcFace](https://insightface.ai/arcface):用于深度人脸识别的加性角度边缘损失。
加性角边距损失 (ArcFace) 可获得用于人脸识别的高度判别性特征。 由于与超球体上的测地线距离精确对应,因此 ArcFace 具有清晰的几何解释。
通过对所有最近最先进的人脸识别方法最广泛的实验评估,10 张人脸识别基准测试,包括具有万亿级对的新大规模图像数据库和大规模视频数据集。结果表明,ArcFace 的性能优于其他技术,且能轻松实现。所有经过改进的训练数据、训练代码、预训练模型和训练日志均已发布,便于开发者重现结果。
官方已给出相应的部署方案
详见:[insightface/recognition/arcface_mxnet at master](https://github.com/deepinsight/insightface/tree/master/recognition/arcface_mxnet)
特征 x 和中心 W 上的并行加速。设置:ResNet 50,批量大小 8 x 64,特征尺寸 512,浮点数 32,GPU 8 x P40 (24GB)。
通过矩阵分区进行并行计算。设置:ResNet 50,批量大小 8 x 64,特征维度 512,浮点数 32,标识号 100 万,GPU 8 x 1080ti (11GB)。训练速度:800 个样本/秒。
#### 示例
使用 GPU 支持进行安装。`MXNet`
```
pip install mxnet-cu100 # mxnet-cu102
```
克隆 InsightFace 存储库。
```
git clone --recursive https://github.com/deepinsight/insightface.git
```
下载训练集并将其放置在 `$INSIGHTFACE_ROOT/recognition/datasets/` 中。每个训练数据集包括以下 6 个文件:`MS1MV2-Arcface`
```python
faces_emore/
train.idx
train.rec
property
lfw.bin
cfp_fp.bin
agedb_30.bin
```
前三个文件是训练数据集,而后三个文件是验证集。
##### 训练深度人脸识别模型
进入 `$INSIGHTFACE_ROOT/recognition/ArcFace` 目录
放置和编辑配置文件
```
cp sample_config.py config.py
vim config.py # edit dataset path etc..
```
下面给出一些示例,实验基于 Tesla P40 GPU 硬件平台
(1)使用 LResNet100E-IR 训练 ArcFace
```
CUDA_VISIBLE_DEVICES='0,1,2,3' python -u train.py --network r100 --loss arcface --dataset emore
```
每 2000 批输出 LFW、CFP-FP 和 AgeDB-30 的验证结果。您可以在 config.py 中检查所有选项。
(2)使用 LResNet50E-IR 训练 CosineFace
```
CUDA_VISIBLE_DEVICES='0,1,2,3' python -u train.py --network r50 --loss cosface --dataset emore
```
(3)使用 MobileFaceNet 训练 Softmax
```
CUDA_VISIBLE_DEVICES='0,1,2,3' python -u train.py --network y1 --loss softmax --dataset emore
```
(4)对上述具有 Triplet 损失的 Softmax 模型进行微调
```
CUDA_VISIBLE_DEVICES='0,1,2,3' python -u train.py --network mnas05 --loss triplet --lr 0.005 --pretrained ./models/y1-softmax-emore,1
```
### RKNN-Toolkit2
运行 RKNN-Toolkit2 工具,将训练好的模型转换为 RKNN 格式的模型,然后在开发板上使用 RKNN C API 或 Python API 进行推理。
在 Linux 系统下部署 RKNN-Toolkit2 工具
```bash
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-4.6.14-Linux-x86_64.sh
```
为了适配相关软件包,需要安装较低版本的 Conda 和 Python v3.80,安装步骤可以参考之前的帖子。
安装 OpenCV 库
```bash
pip install rknn-toolkit2/packages/rknn_toolkit2-1.6.0+81f21f4d-cp38-cp38-linux_x86_64.whl
pip install opencv-python-headless
git clone https://github.com/airockchip/rknn_model_zoo.git
```
RKNN 模型转换,官网获取源码
```bash
git clone https://github.com/LuckfoxTECH/luckfox_pico_rknn_example.git
```
使用 convert.py 指令转换模型
```python
python convert.py
```
使用 Facenet 模型进行面部特征提取,并存储在特征向量
```python
// 为每张参考人脸分配特征向量
float* reference_out_fp32_one = (float*)malloc(sizeof(float) * 128);
float* reference_out_fp32_two = (float*)malloc(sizeof(float) * 128);
float* reference_out_fp32_thr = (float*)malloc(sizeof(float) * 128);
// 提取每张参考人脸的特征
letterbox(one, facenet_input);
ret = rknn_run(app_facenet_ctx.rknn_ctx, nullptr);
if (ret < 0) {
printf("rknn_run fail! ret=%d\n", ret);
return -1;
}
output = (uint8_t *)(app_facenet_ctx.output_mems[0]->virt_addr);
output_normalization(&app_facenet_ctx, output, reference_out_fp32_one);
letterbox(two, facenet_input);
ret = rknn_run(app_facenet_ctx.rknn_ctx, nullptr);
if (ret < 0) {
printf("rknn_run fail! ret=%d\n", ret);
return -1;
}
output = (uint8_t *)(app_facenet_ctx.output_mems[0]->virt_addr);
output_normalization(&app_facenet_ctx, output, reference_out_fp32_two);
letterbox(thr, facenet_input);
ret = rknn_run(app_facenet_ctx.rknn_ctx, nullptr);
if (ret < 0) {
printf("rknn_run fail! ret=%d\n", ret);
return -1;
}
output = (uint8_t *)(app_facenet_ctx.output_mems[0]->virt_addr);
output_normalization(&app_facenet_ctx, output, reference_out_fp32_thr);
```
对摄像头采集到的人脸进行特征提取,并与目标人脸特征进行对比。需 RetinaFace 模型从环境中识别出人脸
```python
def forward(self,inputs):
# resnet中抽取特征
out = self.body(inputs)
# FPN
fpn = self.fpn(out)
# SSH
feature1 = self.ssh1(fpn[0])
feature2 = self.ssh2(fpn[1])
feature3 = self.ssh3(fpn[2])
features = [feature1, feature2, feature3]
bbox_regressions = torch.cat([self.BboxHead(feature) for i, feature in enumerate(features)], dim=1)
classifications = torch.cat([self.ClassHead(feature) for i, feature in enumerate(features)],dim=1)
ldm_regressions = torch.cat([self.LandmarkHead(feature) for i, feature in enumerate(features)], dim=1)
if self.phase == 'train':
output = (bbox_regressions, classifications, ldm_regressions)
else:
output = (bbox_regressions, F.softmax(classifications, dim=-1), ldm_regressions)
return output
```
## 开发环境部署
确认 Luckfox-pico SDK 已正确安装,确认交叉编译链的环境变量设置正确.
安装过程在前面的帖子中已有介绍,详见:[#AI挑战营(进阶)# 模型部署 ](https://bbs.eeworld.com.cn/thread-1303704-1-1.html) .
主要步骤包括:
1.使用 Git 工具拉取最新 SDK
```bash
git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git
```
2.安装交叉编译工具链
```bash
cd luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/
source env_install_toolchain.sh
```
3.编译镜像文件
```bash
cd luckfox-pico
# 这里使用busybox/buildroot
./build.sh lunch
./build.sh
```
编译完成效果
使用编译好的 buildroot 镜像或使用官方镜像。
需要确保摄像头驱动、 rknpu 驱动和 rockit 驱动、 rkisp 驱动等成功被加载。 板端执行 `lsmod` 验证。
### 上传工程
Type-C 数据线连接开发板和电脑;
使用 ADB 方式连接开发板,检查设备状态,是否识别;
```bash
adb devices
adb shell
ls
exit
```
返回电脑根目录,输入 push 文件夹命令
```bash
adb push D:\HFR /
```
adb 推送文件语法:`adb push `
进入设备文件根目录,检查文件夹是否存在
进入目标文件夹 `HFR`,修改目标执行文件的权限,并运行目标文件
```bash
adb shell
cd HFR
chmod 777 luckfox_pico_rtsp_face
./luckfox_pico_rtsp_face ./model/face1.jpg
```
> 若提示推流窗口被占用,则执行 `RkLunch-stop.sh` 停止推流
```bash
adb shell
cd oem/usr/bin
RkLunch-stop.sh
```
之后重新运行目标人脸识别程序即可。
打开 VLC media player 软件,依次进入媒体 - 打开网络串流 - 网络 - 输入URL
`rtsp://172.32.0.93/live/0`
点击 `播放`,即可实现开发板对摄像头数据的推流显示。
## 效果
人脸模型使用美剧 *老友记 (Friends)* 的剧照
录入人脸模型图片
电脑屏幕的识别效果
手机屏幕图片的人脸识别效果
识别准确率为 73%
更换人脸模型为 `face2.jpg` 之后的识别效果
更换人脸模型为 `face3.jpg` 后的识别效果
## 总结
本文介绍了人脸识别的主要实现流程,利用 ArcFace 和 RetinaFace 模型实现高效、快速的人脸检测和识别。模型特征提取,通过 rknn-toolkit2 工具包对模型进行转换,并实现模型的开发板部署,展示了测试结果。为相关领域的开发和应用提供了参考。
- 2025-01-12
-
回复了主题帖:
[RV1106&InsightFace]--InsightFace实现视频中的人脸识别
膜拜大佬啊,太强了,识别效果好,题材(桃园三结义)也很棒
- 2025-01-06
-
回复了主题帖:
#AI挑战营(进阶)# 模型部署
Jacktang 发表于 2025-1-6 07:28
识别效果显著提升,识别准确率在 60% 左右,波动确实比较大,什么原因
识别波动大,还是和环境对比度有关。一旦摄像头的采集图像存在较为复杂的环境或多种物体干扰,被框选的部分大多数情况下是物体,而不是数字……简言之就是还不够智能
比如,摄像头采集周围环境,识别数字往往仅通过对比度降帧匹配给出结果,如下图所示
还发现识别率和拍摄角度有关,如果数字是倾斜或者倒立的情况,识别效果大幅降低,这种情况可以通过添加训练模型、多次迭代、增加样本数量等方法得以改善。
- 2025-01-05
-
发表了主题帖:
#AI挑战营(进阶)# 模型部署
# #AI挑战营(进阶)# 模型部署
本文介绍了将前面获得的模型转化后,部署至开发板的主要流程,包括RKNN模型转化、SDK部署、编译工程、移植工程、运行和测试工程。
## 简介
这里先介绍几个概念
- **ONNX**(Open Neural Network Exchange)是一个开放的生态系统,它允许AI开发者在不同的框架和工具之间轻松地移动模型。ONNX定义了一个用于机器学习模型的开放格式,使得模型可以在不同的深度学习框架之间进行转换和使用;
- **RKNN**(Rockchip Neural Network)是瑞芯微电子公司为其NPU(神经网络处理单元)设计的一套工具和库。它支持将多种深度学习框架训练的模型转换为RKNN格式,进而在Rockchip NPU上进行高效的推理;
- **NPU** (Nerual Processing Unit)神经网络处理单元,专门设计用于高效执行深度学习模型推理的硬件加速器;
- **RKNPU** 内置于瑞芯微处理器的 NPU 被称为 RKNPU;
LuckFox Pico 系列开发板了搭载瑞芯微 RV1103/RV1106 芯片,内置瑞芯微自研第 4 代 NPU。该 NPU 具有高运算精度,支持int4、int8、int16混合量化。其中,int8 算力为 0.5TOPs,int4 算力可达 1.0TOPs。
RKNPU4.0 被划分为 RKNPU2,因此要使用 RKNPU2 的 SDK 和工具套件。
### rknn-Toolkit2
RKNN-Toolkit2 工具在 PC 平台上提供 C 或 Python 接口,简化模型的部署和运行。用户可以通过该工具轻松完成以下功能:模型转换、量化、推理、性能和内存评估、量化精度分析以及模型加密。RKNN 软件栈可以帮助用户快速的将 AI 模型部署到 Rockchip 芯片。
为了使用 RKNPU,用户需要先在电脑上运行 RKNN-Toolkit2 工具,将训练好的模型转换为 RKNN 格式的模型,然后在开发板上使用 RKNN C API 或 Python API 进行推理。
- RKNN-Toolkit2 是一款软件开发套件,供用户在 PC 和 Rockchip NPU 平台上进行模型转换、推理和性能评估。
- RKNN-Toolkit-Lite2 为 Rockchip NPU 平台提供 Python 编程接口,帮助用户部署 RKNN 模型,加速 AI 应用的落地。
- RKNN Runtime 为 Rockchip NPU 平台提供 C/C++ 编程接口,帮助用户部署 RKNN 模型,加速 AI 应用的落地。
- RKNPU 内核驱动负责与 NPU 硬件交互。它一直是开源的,可以在 Rockchip 内核代码中找到。
支持的平台包括
- RK3588 Series
- RK3576 Series
- RK3566/RK3568 Series
- RK3562 Series
- RV1103/**RV1106**
- RV1103B/RV1106B
- RK2118
根据 [rknn-toolkit2](https://github.com/airockchip/rknn-toolkit2) 支持的 Python 版本,这里使用较新的 Python 3.12
使用虚拟机安装 Ubuntu 系统,或安装 Anaconda 软件,镜像[下载](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/) .
安装 Python 3.12 或其他适用版本。
克隆 rknn-toolkit2
```bash
git clone https://github.com/airockchip/rknn-toolkit2
```
> 该安装包或压缩包需占用 1.44 G 空间,注意分配
安装 rknn-toolkit2 所需 Python 环境
```bash
sudo apt-get update
sudo apt-get install python3 python3-dev python3-pip
sudo apt-get install libxslt1-dev zlib1g zlib1g-dev libglib2.0-0 libsm6 libgl1-mesa-glx libprotobuf-dev gcc
```
安装依赖包
```bash
pip3 install -r rknn-toolkit2/packages/requirements_cp312-1.6.0.txt
```
安装 rknn-toolkit2
```
pip3 install rknn-toolkit2/packages/rknn_toolkit2-1.6.0+81f21f4d-cp310-cp310-linux_x86_64.whl
```
验证 rknn-toolkit2 是否安装成功
```python
from rknn.api import RKNN
```
### Conda
[下载](https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py39_24.11.1-0-Linux-x86_64.sh) 并安装 Conda
```bash
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py39_24.11.1-0-Linux-x86_64.sh
chmod 777 Miniconda3-py39_24.11.1-0-Linux-x86_64.sh
bash Miniconda3-py39_24.11.1-0-Linux-x86_64.sh
```
安装需要阅读许可协议等,按 Enter 键即可。
> 注意这里需要新建 conda 环境,名称和密码等信息;
>
> 这里使用 `toolkit2` 命名环境。
最后需要关闭并重新打开终端才可执行 conda 指令。
输入 `conda -V` 查询当前 conda 版本,或 `conda env list` 查询环境列表
创建 RKNN-Toolkit2 的 Conda 开发环境
```bash
conda create -n RKNN-Toolkit2 python=3.12
```
安装 RKNN-Toolkit2 的 Python 依赖库
```python
pip install tf-estimator-nightly==2.8.0.dev2021122109
pip install -r /home/ljl/rv1106/rknn-toolkit2-2.3.0/rknn-toolkit2/packages/x86_64/requirements_cp38-1.6.0.txt -i https://pypi.mirrors.ustc.edu.cn/simple/
```
> 这里已下载 rknn-toolkit2 的相关文件,通过镜像安装所需 Python 库文件。
安装 RKNN-Toolkit2
```python
pip install /home/ljl/rv1106/rknn-toolkit2-2.3.0/rknn-toolkit2/packages/x86_64/rknn-toolkit2/packages/x86_64/rknn_toolkit2-2.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
```
> 注意这里需要安装 cp39 版本,更高版本的 .whl 提示环境问题无法安装。
激活 Conda 环境 toolkit2
```bash
conda env list
conda activate toolkit2
```
克隆 rknn_model_zoo
```bash
git clone https://github.com/airockchip/rknn_model_zoo.git
```
rknn_model_zoo 文件夹下新建文件夹,用来放置前面训练出来的 ONNX 模型
```bash
mkdir myONNXmodel
cd myONNXmodel
ls
```
新建 `transfer.py` 文件执行 Python 转换代码
通过 Python 脚本执行模型转换
```python
from rknn.api import RKNN
# Create RKNN object
rknn = RKNN(verbose=True)
# pre-process config
print('--> config model')
rknn.config(target_platform='rv1106', mean_values=[[28]], std_values=[[28]])
print('done')
# Load model
print('--> Loading model')
ret = rknn.load_onnx(model='./mnist_101_model.onnx')
if ret != 0:
print('Load model failed!')
exit(ret)
print('done')
rknn.build(do_quantization=True, dataset='./data.txt') # 构建RKNN模型,可选参数量化
if ret != 0:
print('Build model failed!')
exit(ret)
print('done')
ret = rknn.export_rknn('./mnist.rknn') # 导出RKNN模型文件
if ret != 0:
print('Export rknn model failed!')
exit(ret)
print('done')
# 释放 RKNN 对象
rknn.release()
```
在 myONNXmodel 文件夹下新建 pic 文件夹
新建 data.txt 文件,指定数据集
`./pic/0-label-5.png`
运行转换python文件 transfer.py
转换可得到目标 rknn 格式文件。
### ADB
通过 ADB 方式登录开发板,详见:[ADB 登录 | LUCKFOX WIKI](https://wiki.luckfox.com/zh/Luckfox-Pico/Luckfox-Pico-Login-ADB) 。
使用 TypeC-USB 数据线连接电脑和开发板
1.系统安装 ADB 驱动,并将 ADB 文件夹路径添加至系统环境变量;
2.打开 CMD 命令行终端,输入 `adb devices` 查询已连接设备;
```powershell
C:\Users\h2457>adb devices
List of devices attached
bd547ee6900c058b device
```
3.输入 `ifconfig` [查询](https://www.oryoy.com/news/shi-yong-adb-ming-ling-zai-android-she-bei-shang-cha-kan-he-pei-zhi-ip-di-zhi-de-xiang-xi-zhi-nan.html)设备 ip 地址;
```powershell
C:\Users\h2457>adb shell
# ifconfig
eth0 Link encap:Ethernet HWaddr FE:E7:53:CE:CA:22
inet addr:192.168.253.10 Bcast:192.168.253.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:299 errors:0 dropped:0 overruns:0 frame:0
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:21738 (21.2 KiB) TX bytes:684 (684.0 B)
Interrupt:52
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
usb0 Link encap:Ethernet HWaddr 5E:49:D7:B7:E0:97
inet addr:172.32.0.93 Bcast:172.32.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3114 errors:0 dropped:1395 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:364838 (356.2 KiB) TX bytes:0 (0.0 B)
```
可知设备静态 IP 为 `172.32.0.93`
## SDK 环境部署
Windows操作系统需要安装 Ubuntu 应用,可在 Microsoft 应用商店搜索安装。
运行 Ubuntu 系统,升级
```bash
sudo apt update
```
安装开发环境
```bash
sudo apt-get install -y git ssh make gcc gcc-multilib g++-multilib module-assistant expect g++ gawk texinfo libssl-dev bison flex fakeroot cmake unzip gperf autoconf device-tree-compiler libncurses5-dev pkg-config bc python-is-python3 passwd openssl openssh-server openssh-client vim file cpio rsync
```
获取最新 [SDK](https://gitee.com/LuckfoxTECH/luckfox-pico)
```c++
git clone https://gitee.com/LuckfoxTECH/luckfox-pico.git
```
安装交叉编译工具链
```bash
cd luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/
source env_install_toolchain.sh
```
全部编译镜像文件
```bash
cd luckfox-pico
# 这里使用busybox/buildroot
./build.sh lunch
./build.sh
```
> 需要注意,这里使用 Windows 11 安装桌面 Ubuntu 会报错,提示路径包含空格等,因此采用虚拟机安装Linux系统。
>
> 虚拟机下载:[VMware Workstation Pro v17.6.2](https://www.ghxi.com/vmware17.html)
- 设备选择: `[6] RV1106_Luckfox_Pico_Max`
- 启动媒介选择: `[1] SPI_NAND`
- 系统版本选择: `[0] Buildroot(Support Rockchip official features)`
编译成功
> 第一次编译镜像需要较长时间(约两小时),主要是自动下载和安装缺少的软件。
## 编译工程
克隆代码并检查文件列表
编译代码,生成目标文件,`luckfox_rtsp_mnist_dir`
> 也可直接移植克隆下来的文件夹
## 移植工程
将其移植到开发板,
```bash
adb -s bd547ee6900c058b push D:\RV1106\luckfox_rtsp_mnist\luckfox_rtsp_mnist_dir /work
```
adb 推送文件语法:`adb -s push `
移植完成提示如下
## 运行
adb 连接开发板,
下载并安装 VCL 软件,
媒体 - 打开网络串流 - 网络 - 输入URL
`rtsp://172.32.0.93/live/0`
点击 `播放` 即可。
rtsp 推流效果
停止默认的 rtsp 推流
```bash
adb devices
adb shell
cd oem/usr/bin
RkLunch-stop.sh
```
修改执行文件的权限,运行推流指令
```bash
cd /
cd work
chmod 777 luckfox_rtsp_mnist
./luckfox_rtsp_mnist ./model/model.rknn
```
## 效果测试
### 1. 手机显示屏
为了使对比度更加显著,使用手机显示屏或电脑显示器书写数字(手写数字识别[网站](https://henryjin.dev/demo/mnist/) )
识别效果一般,尝试在 A4 纸使用马克笔手写数字
### 2. A4纸
识别效果显著提升,识别准确率在 60% 左右,波动较大。与显示器识别的情况进行对比可知,画质(分辨率)和对比度(与环境亮度有关)是改善识别效果的关键因素。
### 3. 液晶显示器
使用 PowerPoint 荧光笔手写数字
显示效果更为稳定,识别率稳定在 0.6 附近。因此,提高对比度有助于提高识别的稳定性。
## 总结
本文介绍了手写数字识别的模型部署流程,通过 Ubuntu 系统部署 Luckfox SDK 框架,编译已训练好的 RKNN 模型,得到最终的可在开发板执行的命令文件。之后将文件上传至开发板,并 rtsp 推流显示。
分别使用显示器和 A4 纸手写数字来验证模型的识别效果,准确率在 60% 上下,还有继续提升的空间。
- 2025-01-01
-
回复了主题帖:
祝福2025!回帖即有奖!选取最有心的送5块国产开发板!
回顾2024,测评了许多国产开发板,有灵动、芯源、雅特力、极海、敏矽微、富芮坤等等,还有高性能开发板如龙芯中科、赛昉·星光2等,切实感受到了国产芯片的崛起和壮大,硬件进步的同时,很欣慰地看到大家越来越重视软件和生态的建设,各大论坛也在不断助力推广国产芯片崛起……新的一年,我将继续活跃在论坛,为大家带来更多创新推文,为国产芯片的发展壮大添砖加瓦!
- 2024-12-30
-
发表了主题帖:
#AI挑战营(进阶)# 模型训练
# #AI挑战营(进阶)# 模型训练
在完成前面环境搭建的基础上,这里介绍手写数字识别的模型训练流程。
## 1.准备工作
确认库函数安装完成,命令行终端执行如下代码
```powershell
pip install torchvision
pip install tqdm
pip install matplotlib
```
> - 这里需要 **tqdm** 库实现训练的可视化,它是一个动态显示库。
> - 需要 **matplotlib** 库用来实现科学绘图,呈现训练结果、保真度等结果,为后续的模型部署、可靠性等指标提供重要参考依据。
## 2.流程图
## 3.训练过程
### 数据预处理
1.导入相关库函数
2.定义训练硬件基础,CPU 或 GPU,这里采用 CPU 训练
3.使用图片处理库 `torchvision.transforms` 将图片转换为网络张量
4.构建数据集,调用已下载的 MNIST 数据集、训练集和测试集,调用 `DataLoader` 函数进行训练;
### 模型训练
1.使用卷积神经网络基础结构
2.构建模型实例,将图形张量置于指定 CPU 或 GPU 设备,
3.构建迭代器与损失函数,使用 Adam 迭代器,使用交叉熵损失函数;
4.构建训练循环,即 `训练、验证、训练、验证 ...` 流程,构建训练的循环框架
5.代码测试
```python
#构造临时变量
#关闭模型的训练状态
#对测试集的DataLoader进行迭代
#存储测试结果
#计算总测试的平均准确率
#计算总测试的平均Loss
#将本step结果进行可视化处理
```
6.训练的循环代码
### 数据后处理
包括训练结果提取、**可视化**展示、模型**保存**等。
1.使用 `matplotlib` 实现可视化训练结果,展示损失函数、保真度反馈等信息;
```python
#损失函数可视化
matplotlib.pyplot.plot(history['Test Loss'],label = 'Test Loss')
matplotlib.pyplot.legend(loc='best')
matplotlib.pyplot.grid(True)
matplotlib.pyplot.xlabel('Epoch')
matplotlib.pyplot.ylabel('Loss')
matplotlib.pyplot.show()
#保真度可视化
matplotlib.pyplot.plot(history['Test Accuracy'],color = 'red',label = 'Test Accuracy')
matplotlib.pyplot.legend(loc='best')
matplotlib.pyplot.grid(True)
matplotlib.pyplot.xlabel('Epoch')
matplotlib.pyplot.ylabel('Accuracy')
matplotlib.pyplot.show()
```
2.模型保存,可选择部分保存或整体模型保存;
```c++
torch.save(net,'./model.pth')
```
## 4.代码
```python
# 初始化
import torch
import torchvision
from tqdm import tqdm
import matplotlib
# 构建模型
class Net(torch.nn.Module):
def __init__(self):
super(Net,self).__init__()
self.model = torch.nn.Sequential(
#The size of the picture is 28x28
torch.nn.Conv2d(in_channels = 1,out_channels = 16,kernel_size = 3,stride = 1,padding = 1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size = 2,stride = 2),
#The size of the picture is 14x14
torch.nn.Conv2d(in_channels = 16,out_channels = 32,kernel_size = 3,stride = 1,padding = 1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size = 2,stride = 2),
#The size of the picture is 7x7
torch.nn.Conv2d(in_channels = 32,out_channels = 64,kernel_size = 3,stride = 1,padding = 1),
torch.nn.ReLU(),
torch.nn.Flatten(),
torch.nn.Linear(in_features = 7 * 7 * 64,out_features = 128),
torch.nn.ReLU(),
torch.nn.Linear(in_features = 128,out_features = 10),
torch.nn.Softmax(dim=1)
)
def forward(self,input):
output = self.model(input)
return output
# 图片张量转换
device = "cuda:0" if torch.cuda.is_available() else "cpu"
transform = torchvision.transforms.Compose([torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize(mean = [0.5],std = [0.5])])
# 迭代器生成
BATCH_SIZE = 256
EPOCHS = 10 # 循环次数
trainData = torchvision.datasets.MNIST('./data/',train = True,transform = transform,download = True)
testData = torchvision.datasets.MNIST('./data/',train = False,transform = transform)
trainDataLoader = torch.utils.data.DataLoader(dataset = trainData,batch_size = BATCH_SIZE,shuffle = True)
testDataLoader = torch.utils.data.DataLoader(dataset = testData,batch_size = BATCH_SIZE)
# 模型实例
net = Net()
print(net.to(device))
# 损失函数、迭代器
lossF = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters())
# 构建循环框架
history = {'Test Loss':[],'Test Accuracy':[]}
for epoch in range(1,EPOCHS + 1):
processBar = tqdm(trainDataLoader,unit = 'step')
net.train(True)
for step,(trainImgs,labels) in enumerate(processBar):
trainImgs = trainImgs.to(device)
labels = labels.to(device)
net.zero_grad()
outputs = net(trainImgs)
loss = lossF(outputs,labels)
predictions = torch.argmax(outputs, dim = 1)
accuracy = torch.sum(predictions == labels)/labels.shape[0]
loss.backward()
optimizer.step()
processBar.set_description("[%d/%d] Loss: %.4f, Acc: %.4f" %
(epoch,EPOCHS,loss.item(),accuracy.item()))
if step == len(processBar)-1:
correct,totalLoss = 0,0
net.train(False)
with torch.no_grad():
for testImgs,labels in testDataLoader:
testImgs = testImgs.to(device)
labels = labels.to(device)
outputs = net(testImgs)
loss = lossF(outputs,labels)
predictions = torch.argmax(outputs,dim = 1)
totalLoss += loss
correct += torch.sum(predictions == labels)
testAccuracy = correct/(BATCH_SIZE * len(testDataLoader))
testLoss = totalLoss/len(testDataLoader)
history['Test Loss'].append(testLoss.item())
history['Test Accuracy'].append(testAccuracy.item())
# 单次循环结果的记录和可视化处理
processBar.set_description("[%d/%d] Loss: %.4f, Acc: %.4f, Test Loss: %.4f, Test Acc: %.4f" %
(epoch,EPOCHS,loss.item(),accuracy.item(),testLoss.item(),testAccuracy.item()))
processBar.close()
# 结果可视化
matplotlib.pyplot.plot(history['Test Loss'],label = 'Test Loss')
matplotlib.pyplot.legend(loc='best')
matplotlib.pyplot.grid(True)
matplotlib.pyplot.xlabel('Epoch')
matplotlib.pyplot.ylabel('Loss')
matplotlib.pyplot.show()
matplotlib.pyplot.plot(history['Test Accuracy'],color = 'red',label = 'Test Accuracy')
matplotlib.pyplot.legend(loc='best')
matplotlib.pyplot.grid(True)
matplotlib.pyplot.xlabel('Epoch')
matplotlib.pyplot.ylabel('Accuracy')
matplotlib.pyplot.show()
# 模型保存
torch.save(net,'./model.pth')
```
## 5.效果
由于使用 CPU 进行训练,所需时间较长,迭代 10 次所需时间为 216 小时
> 这里使用的 CPU 型号为 Intel(R) Core(TM) **i5-10400** CPU @ **2.90GHz**
## 方案二
可使用如下代码测试,加快速度
基于 PyTorch 框架,采用 CNN 卷积神经网络实现 MNIST 手写数字识别
### 代码
```python
import torch
import numpy as np
from matplotlib import pyplot as plt
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision import datasets
import torch.nn.functional as F
"""
卷积运算 使用mnist数据集,和10-4,11类似的,只是这里:1.输出训练轮的acc 2.模型上使用torch.nn.Sequential
"""
# Super parameter ------------------------------------------------------------------------------------
batch_size = 64
learning_rate = 0.01
momentum = 0.5
EPOCH = 10
# Prepare dataset ------------------------------------------------------------------------------------
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))])
# softmax归一化指数函数(https://blog.csdn.net/lz_peter/article/details/84574716),其中0.1307是mean均值和0.3081是std标准差
train_dataset = datasets.MNIST(root='./data/mnist', train=True, transform=transform, download=True) # 本地没有就加上download=True
test_dataset = datasets.MNIST(root='./data/mnist', train=False, transform=transform) # train=True训练集,=False测试集
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
fig = plt.figure()
for i in range(12):
plt.subplot(3, 4, i+1)
plt.tight_layout()
plt.imshow(train_dataset.train_data, cmap='gray', interpolation='none')
plt.title("Labels: {}".format(train_dataset.train_labels))
plt.xticks([])
plt.yticks([])
plt.show()
# 训练集乱序,测试集有序
# Design model using class ------------------------------------------------------------------------------
class Net(torch.nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = torch.nn.Sequential(
torch.nn.Conv2d(1, 10, kernel_size=5),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2),
)
self.conv2 = torch.nn.Sequential(
torch.nn.Conv2d(10, 20, kernel_size=5),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2),
)
self.fc = torch.nn.Sequential(
torch.nn.Linear(320, 50),
torch.nn.Linear(50, 10),
)
def forward(self, x):
batch_size = x.size(0)
x = self.conv1(x) # 一层卷积层,一层池化层,一层激活层(图是先卷积后激活再池化,差别不大)
x = self.conv2(x) # 再来一次
x = x.view(batch_size, -1) # flatten 变成全连接网络需要的输入 (batch, 20,4,4) ==> (batch,320), -1 此处自动算出的是320
x = self.fc(x)
return x # 最后输出的是维度为10的,也就是(对应数学符号的0~9)
model = Net()
# Construct loss and optimizer ------------------------------------------------------------------------------
criterion = torch.nn.CrossEntropyLoss() # 交叉熵损失
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, momentum=momentum) # lr学习率,momentum冲量
# Train and Test CLASS --------------------------------------------------------------------------------------
# 把单独的一轮一环封装在函数类里
def train(epoch):
running_loss = 0.0 # 这整个epoch的loss清零
running_total = 0
running_correct = 0
for batch_idx, data in enumerate(train_loader, 0):
inputs, target = data
optimizer.zero_grad()
# forward + backward + update
outputs = model(inputs)
loss = criterion(outputs, target)
loss.backward()
optimizer.step()
# 把运行中的loss累加起来,为了下面300次一除
running_loss += loss.item()
# 把运行中的准确率acc算出来
_, predicted = torch.max(outputs.data, dim=1)
running_total += inputs.shape[0]
running_correct += (predicted == target).sum().item()
if batch_idx % 300 == 299: # 不想要每一次都出loss,浪费时间,选择每300次出一个平均损失,和准确率
print('[%d, %5d]: loss: %.3f , acc: %.2f %%'
% (epoch + 1, batch_idx + 1, running_loss / 300, 100 * running_correct / running_total))
running_loss = 0.0 # 这小批300的loss清零
running_total = 0
running_correct = 0 # 这小批300的acc清零
# torch.save(model.state_dict(), './model_Mnist.pth')
# torch.save(optimizer.state_dict(), './optimizer_Mnist.pth')
def test():
correct = 0
total = 0
with torch.no_grad(): # 测试集不用算梯度
for data in test_loader:
images, labels = data
outputs = model(images)
_, predicted = torch.max(outputs.data, dim=1) # dim = 1 列是第0个维度,行是第1个维度,沿着行(第1个维度)去找1.最大值和2.最大值的下标
total += labels.size(0) # 张量之间的比较运算
correct += (predicted == labels).sum().item()
acc = correct / total
print('[%d / %d]: Accuracy on test set: %.1f %% ' % (epoch+1, EPOCH, 100 * acc)) # 求测试的准确率,正确数/总数
return acc
# Start train and Test --------------------------------------------------------------------------------------
if __name__ == '__main__':
acc_list_test = []
for epoch in range(EPOCH):
train(epoch)
# if epoch % 10 == 9: #每训练10轮 测试1次
acc_test = test()
acc_list_test.append(acc_test)
plt.plot(acc_list_test)
plt.xlabel('Epoch')
plt.ylabel('Accuracy On TestSet')
plt.show()
```
代码文件见附件。
**训练结果**
训练识别精度演化曲线
训练过程
## 6.总结
本文阐述了数字识别模型训练的整体逻辑框架,并使用 PyTorch 平台对 MNIST 数据集进行 10 次轮询模拟训练,取得了较好的实验结果,为后续模型部署做好准备。
- 2024-12-26
-
加入了学习《【Follow me第二季第4期】任务汇报》,观看 【Follow me第二季第4期】任务汇报