嵌入式AI快速入门课程-K510篇 (第三篇 环境搭建及开发板操作)
第三篇 环境搭建及开发板操作
文章目录
- 第三篇 环境搭建及开发板操作
- 1.配置VMware使用桥接网卡
- 1.1 vmware设置
- 1.2 虚拟网络编辑器设置
- 2.安装软件
- 2.2 安装 Windows 软件
- 2.3 使用MobaXterm远程登录Ubuntu
- 2.4 使用FileZilla在Windows和Ubuntu之间传文件
- 2.5编程示例:Ubuntu上的Hello程序
- 2.5.1 用Source Insight编写hello.c
- 2.5.2 用FileZilla上传源码
- 1.1.1 编译、运行程序
- 3.DongshanPI-Vision开发板基本操作
- 3.1 DongshanPI-Vision开发板硬件资源简介
- 3.2 DongshanPI-Vision开发板软件资源介绍
- 3.2.1 开发开发环境
- 3.2.2 核心软件
- 3.2.3 文件系统
- 3.3 启动方式选择
- 3.4 开发板硬件连接
- 3.4.1 天线连接
- 3.4.2 连接摄像头
- 3.4.3 连接显示屏
- 3.4.4串口及OTG连接
- 3.5 查看串口端口号
- 3.6 使用MobaXterm软件打开串口
- 3.7 通过串口操作开发板
- 3.8 开机自启应用程序
- 3.9 更新系统
- 3.9.1 更新EMMC系统
- 3.9.1.1 硬件操作
- 3.9.1.2 安装串口驱动
- 3.9.1.3 烧录镜像
- 3.9.1.4 安装烧录驱动
- 3.9.1.5 完整烧录镜像
- 3.9.1.6 启动EMMC系统
- 3.9.2 制作SD卡镜像
- 3.9.2.1 格式化microSD卡
- 3.9.2.2 使用Etcher烧录镜像
- 3.9.2.3 启动SD卡系统
- 3.10 使用wifi连接网络
- 3.10.1 结束开启联网脚本
- 3.10.2 填写WIFI信息
- 3.10.3 连接WiFi
- 3.11 使用TFTP服务在Ubuntu和开发板传输文件
- 3.11.1 Ubuntu安装TFTP服务
- 3.11.2 开发板通过tftp传输文件
- 3.12 配置开发板SSH功能
- 3.12.1 修改ssh配置文件
- 3.12.2 启动ssh
- 3.12.3 连接ssh
- 3.12.4 使用MobaXterm传输文件
- 4.系统功能及AI应用初体验
- 4.1 系统功能体验指南
- 4.1.1 ai demo程序
- 4.1.2 ffmpeg
- 4.1.3 alsa_demo
- 4.1.4 TWOD demo
- 4.1.5 RTC demo
- 4.1.6 WDT demo
- 4.1.7 UART demo
- 4.1.8 ETH demo
- 4.1.9 SDMMC demo
- 4.1.10 SHA/AES demo
- 4.1.11 TRNG demo
- 4.1.12 DRM demo
- 4.1.13 V4L2_DRM demo
- 4.1.14 LVGL demo
- 4.1.15 PWM demo
- 4.1.16 WIFI demo
- 4.1.17 GPIO_KEYS demo
- 4.2 AI应用体验指南
- 4.2.1人脸对齐
- 4.2.2人脸检测
- 人脸检测器-bf16
- 人脸检测器-uint8
- 4.2.3人脸表情识别
- 4.2.4人脸关键点检测
- 4.2.5人脸识别
- 5.2.6人形检测
- 人体关键点检测-openpose
- 人体关键点检测-YOLOV5S
- 4.2.7指尖指定区域识别
- 4.2.8头部态角估计
- 4.2.9车牌识别
- 4.2.10YOLOV5目标检测
- YOLOV5目标检测-bf16
- YOLOV5目标检测-uint8
- 4.2.11自学习KNN算法
- 5.编写一个简单的helloword程序
- 5.1 编写helloword应用程序
- 5.2.编写Makefile编译规则
- 5.3 交叉编译hellowrod程序
- 5.2 上传程序到开发板上运行
- 6.编译一个简单的AI demo程序
- 6.1 编译hello AI的demo程序
- 6.2 上传程序到开发板运行
- 6.3 hello AI程序讲解
- 6.3.1 程序框架
- 6.3.2 程序讲解
- 7.嵌入式开发
- 7.1编译工具链
- 7.2 交叉编译工具链
- 7.3 获得合适的交叉编译工具链
- 7.4 Makefile构建工具
- 7. 5 CMake构建工具
1.配置VMware使用桥接网卡
1.1 vmware设置
使用桥接模式下,虚拟主机与真实主要在VMnet0构成的局域网内通信,同时通过真实主机中的网关与外网通信,即可实现Ubuntu与开发板进行文件传输。
设置网络适配器为桥接模式。
点击网络适配器 NAT,将网络连接方式选择为桥接模式。
1.2 虚拟网络编辑器设置
在开始菜单搜索“虚拟网络编辑器”,点击“以管理员身份运行”打开虚拟网络编辑器:
参考图 1.4,点击“VMnet0”,选择“桥接模式”,在桥接模式下的“已桥接至”下拉框中,选中你电脑中实际使用WIFI网卡,最后点击确定即可完成vmware配置。
注意:必须是“VMnet0”,如果没有“VMnet0”可以点击“添加网络”。
2.安装软件
2.2 安装 Windows 软件
“<开发板配套资料>\2_DongshanPI-Vision_配套工具\”
在网盘资料包的上述目录中,可以得到一系列的安装软件,建议全部安装。有如下软件:
软件名 | 说明 |
---|---|
VMwareWorkstation | 虚拟机软件,安装时需要用到管理员权限 |
SD Card Formatter | SD卡格式化工具 |
MobaXterm | 串口工具、远程登录工具 |
Filezilla | 文件传输工具,在Windows和Ubuntu之间传输文件 |
Source insight | 阅读、编写源码的工具,即装即用;推荐初学者使用 |
2.3 使用MobaXterm远程登录Ubuntu
先确认Ubuntu的IP,在Ubuntu终端执行ifconfig
命令确定桥接网卡IP(注意:这个IP过一段时间会发生变化,那就使用新IP重新连接),如图 2.3所示:
安装、运行MobaXterm,如下建立Session:
按图 2.4操作后,在MobaXterm左侧就可以看到图 2.5这项,双击它就可以登录Ubuntu(第1次登录时会提示你输入密码,密码是ubuntu),然后就可以执行各种Linux命令了:
2.4 使用FileZilla在Windows和Ubuntu之间传文件
使用MobaXterm既可以ssh登录又可以传输文件,不过Mobaxterm在传输文件时使用效率上没有 FileZilla高,所以我们推荐Windows和Ubuntu互相传输文件时使用FileZilla。
双击打开FileZilla后,按图 2.6操作:
第1次连接时,会有如图 2.7所示的提示,选择“总是信任”:
在Filezilla中,左边是Windows文件,右边是Ubuntu的文件,如图 2.8:
2.5编程示例:Ubuntu上的Hello程序
本节演示如何在Windows编写程序、上传到Ubuntu,在Ubuntu中编译、执行。只涉及一个简单的Hello程序,使用命令行编译,不涉及Makefile等知识,这些知识在后面的应用基础中讲解。
2.5.1 用Source Insight编写hello.c
启动Source Insight,点击“File”->“New”,新建文件,如图 2.9:
接下来编写代码,保存文件,如图 2.10所示:
图 2.10 SI编写代码并保存
hello.c的源码如下:
#include <stdio.h>
int main(int argc, char **argv)
{printf("hello, world!\n");return 0;
}
2.5.2 用FileZilla上传源码
如图 2.11操作:
1.1.1 编译、运行程序
如图 2.12操作,对于gcc命令的用法在后面讲到应用开发基础时再细讲,这里只是体验一下:
3.DongshanPI-Vision开发板基本操作
3.1 DongshanPI-Vision开发板硬件资源简介
DongshanPI-Vision开发板是围绕着嘉楠 勘智K510芯片构建的,采用64位双核RISC-V架构 ,主频为:800MHz,支持双精度FPU扩展。采用64位DSP扩展,主频为:800MHz。芯片内置通用神经网络引擎KPU,拥有2.5TFLOPS BF16/2.5TOPS INT8算力,支持TensorFlow、PyTorch、ONNX等多种框架的算子库。
特征 | 描述 |
---|---|
处理器 | 嘉楠 勘智K510 |
内存 | 512MB LPDDR3 |
存储 | 4GB EMMC |
WIFI/蓝牙 | 天线:2.4GHz |
视频输出 | MIPI显示(MIPI DSI)/HDMI显示(HDMI)/SPI显示(SPI DSI) |
视频输入 | 两路MIPI摄像头(MIPI CSI *2)/DVP摄像头(DVP Canera) |
音频输入 | MIC咪头 |
音频输出 | 扬声器/耳机 |
其他连接器 | ·TF卡槽 ·2个USB连接器 · JTAG调试口 ·电池接口 |
开发板组成位置
本章节介绍开发板中关键的元器件及位置功能介绍如下所示,各个标号对应的硬件在板子上都写有名字。
开发板正面图:
开发板背面图:
3.2 DongshanPI-Vision开发板软件资源介绍
3.2.1 开发开发环境
3.2.2 核心软件
3.2.3 文件系统
3.3 启动方式选择
板子上的拨码开关用来设置启动方式,支持这3种方式:EMMC启动、SD卡启动、串口烧写。启动方式如表3-1所示:
BOOT MODEL | SW1(BOOT0) | SW2(BOOT1) |
---|---|---|
EMMC | OFF | OFF |
SD | OFF | ON |
串口烧录 | ON | ON |
这3种启动方式的设置示意图 3.7如下:
注意:设置为串口烧录时,不能插上SD卡、TF卡;上电之后才可以插卡。刚出厂的板子在EMMC上烧写了系统,你可以设置为EMMC启动方式。
3.4 开发板硬件连接
3.4.1 天线连接
要使用WIFI,您需要连接DongshanPI-Vision盒子中提供的2.4GHz天线,下面是将天线连接到DongshanPI-Vision开发板的指南。
3.4.2 连接摄像头
要使用摄像头获取图像数据,如果您只单独购买了DongshanPI-Vision开发板,可能还需另外购买MIPI摄像头。下面图片是将MIPI摄像头连接到DongshanPI-Vision开发板的指南。
3.4.3 连接显示屏
要使用显示屏显示摄像头获取的图像,如果您只单独购买了DongshanPI-Vision开发板,可能还需另外购买MIPI显示屏,或者也可直接使用HDMI线连接电脑显示器。下面是将MIPI显示屏连接到DongshanPI-Vision开发板的指南。
3.4.4串口及OTG连接
通过Type-C线将板连接到PC电脑,您可以使用DongshanPI-Vision盒子中的的两条Type-C线。连接指南如下所示:
注意:请直接将两条数据线连接到电脑端,请勿使用USB HUB连接两条Type-C数据线。如果您的电脑没有多余的USB口,可使用5V1A的电源适配器,连接到OTG口进行供电。
一旦开发板套件通电后,核心板上会亮起红灯,红灯位置如下图中蓝色箭头所示:
3.5 查看串口端口号
在接好串口处的Type-C数据线连接电脑和开发板后,打开电脑的设备管理器,并展开端口(COM和LPT)列表。可以看到下图中,连接后的端口号为COM37。开发板上的USB串口芯片可能是CP210x或CH9102,它们的性能是一样的。你电脑上显示的COM序号可能不一样,记住你电脑显示的数字。
如果电脑没有显示出端口号,就需要手动安装驱动,已经将驱动安装包放入网盘资料中了:
图 3.10 USB串口驱动
如果电脑中没有自动安装驱动,在“设备管理器”会有黄色感叹号提示当前连接的是哪种类型的串口芯片,根据提示选择驱动安装。如果提示中有“CP210x”字样则选择“CP210x_Windows_Drivers.zip”,否则就选择另外一个驱动安装。
3.6 使用MobaXterm软件打开串口
打开MobaXterm,点击左上角的“Session”,在弹出的界面选中“Serial”,如下图所示选择端口号(前面设备管理器显示的端口号COM17或COM19)、波特率(Speed 115200)、流控(Flow Control: none),最后点击“OK”即可。步骤如图 3.11所示。
注意:流控(Flow Control)一定要选择none,否则你将无法在MobaXterm中向串口输入数据。
随后显示一个黑色的窗口, 此时打开板子的电源开关,将收到板子串口发过来的数据,如图 3.12所示。
4.进入串口调试控制台后,如果开发板正在启动uboot或者kernel则会不断打印输出信息直到系统完全启动,如果开发板已经完全启动则不会打印信息,可直接按下回车键,进入开发板系统控制台。
3.7 通过串口操作开发板
在串口看到root@canaan
这类登录的提示信息时,输入回车即可,然后就可以执行各种Linux命令了,如图 3.14所示:
3.8 开机自启应用程序
当系统启动后,如果您正常连接两个摄像头和显示屏,系统会在uboot系统启动阶段显示canaan官方logo,效果图如下所示:
当系统完全启动后会自动运行实时预览程序,使用V4L2抓取摄像头图像并实时显示在显示屏上。效果图如下所示:
如果您想结束掉该进程或者想运行其他需要使用摄像头和显示屏的程序,您可以通过在串口终端控制台输入ps
查看所以进程,并找到进程名.为v4l2_drm.out所对对应的进程号,如下所示:
188 root 0:00 ./v4l2_drm.out -f video_drm_1920x1080.conf -e 1 -s
可以看到最前面的为进程号,可能您的进程号和我不一致,这里我的进程号为188,此时我应该输入:
kill -9 188
如果您的进程号不是188,需要将188修改为您实际的进程号才能正常结束该应用程序。
3.9 更新系统
3.9.1 更新EMMC系统
硬件要求:
- DongshanPI-Vision开发板
- Type-c数据线 x2
软件要求:
- DongshanPI-Vision开发板EMMC镜像:https://dongshanpi.cowtransfer.com/s/5482c150ff6147
- KendryteBurningTool 烧录工具:https://dongshanpi.cowtransfer.com/s/b3709a719d2342
开始前请下载DongshanPI-Vision开发板EMMC镜像 ,并记住它在计算机中保存的位置。
3.9.1.1 硬件操作
将下图中的拨码开关的boot0和boot1都向上拨,使开发板进入下载模式。使用两条Type-C线连接开发板端和电脑端,用于给开发板进行供电和使用串口进行烧录EMMC系统。
3.9.1.2 安装串口驱动
- 串口驱动安装程序:
2_DongshanPI-Vision_配套工具/【Windows】串口驱动工具
安装前说明:每台计算机安装一次即可。
打开串口驱动安装软件CH341SER.EXE
,打开后会进入如下界面:
点击安装
等待安装完成即可。
3.9.1.3 烧录镜像
下载EMMC镜像并记住它在计算机中的位置。打开KendryteBurningTool 烧录工具,进入KendryteBurningTool\bin
目录下,双击打开BurningTool.exe
,如下所示的文件。
注意:在使用KendryteBurningTool 烧录工具时需要关闭串口软件和虚拟机,防止串口被占用。
打开BurningTool.exe
程序后会进入如下界面:
点击选择文件,选择下载好的EMMC镜像。选择完成后点击保存,操作步骤如下所示:
保存后需要在串口选择中选择开发板的串口号,当我们将开发板和PC电脑端通过Type-C连接起来后,可以在BurningTool软件中点击红色箭头处查看我开发板的端口号,选择开发板的串口端口号。(我们也可以在设备管理器中确认开发的端口号)
选择完成后,点击开始烧录烧录。如果您不是第一次进行烧录,此时等待成功烧录完成即可。如果您是第一次进行烧录请继续阅读下面的内容。第一次烧录步骤如下所示:
当PC电脑首次进行烧录时,第一个进度条结束后,会显示下图中的错误信息。此时需要安装驱动。
3.9.1.4 安装烧录驱动
- zadig-2.4烧录驱动安装文件:``
安装前说明:每台计算机安装一次即可。
打开zadig-2.4
软件,进入如下界面
点击Option
中的选择List All Devices
(列出所有设备),具体操作如下所示:
上述操作完成后,可以看到在虚线框内出现了设备名,我们需要切换设备为 Mass storage devices
,具体操作如下所示:
点击Replace Driver
替换驱动程序,此时会弹出一个确认窗口,点击是
。
安装完成后会弹出以下窗口点击close
到此烧录驱动成功安装。
3.9.1.5 完整烧录镜像
安装完成烧录镜像后,再次打开BurningTool.exe
烧录工具软件,按照1.3章节中的操作进行烧录即可。完整烧录步骤如下所示:
3.9.1.6 启动EMMC系统
将下图中的拨码开关的boot0和boot1都向下拨,使开发板进入EMMC启动模式。使用两条Type-C线连接开发板端和电脑端,用于给开发板进行供电和使用串口登录开发板控制台。
使用串口软件查看串口控制台,成功启动后会进入开发板控制台。
3.9.2 制作SD卡镜像
硬件要求:
- DongshanPI-Vision开发板
- microSD卡(建议最小8G)
- Type-c数据线 x2
软件要求:
- DongshanPI-Vision开发板SD卡镜像:https://dongshanpi.cowtransfer.com/s/bac8fbdce7c046
- SD卡格式化工具:SD Memory Card Formatter
- SD卡刷机工具:ETCHER
开始前请下载DongshanPI-Vision开发板SD卡镜像,并记住它在计算机中保存的位置。
3.9.2.1 格式化microSD卡
将您的SD卡使用读卡器通过USB口插入您的PC电脑,使用SD卡格式化工具SD Memory Card Formatter格式化您的SD卡。点击下图中红框位置,开始格式化内存卡。
点击完成后会弹出下图所示的提示框,该提示警告我们格式化将清空卡中的所有数据,询问我们是否继续,这里点击是
等待格式化完成后,会弹出以下对话框,提示我们格式化后的文件系统为FAT32
以及内存大小可用空间,点击确定即可完成SD卡的格式化。
3.9.2.2 使用Etcher烧录镜像
使用Etcher将DongshanPI-Vision开发板SD卡镜像写入您的microSD卡。
下载Etcher烧写工具并安装它。启动Etcher应用程序,启动后界面如下图所示:
点击Flash from file
,如下图所示,点击下图红框处。
此时会弹出文件资源管理器,选择您刚刚下载的DongshanPI-Vision开发板SD卡镜像。
选择完成后会,显示下面的界面,点击下图中红框处Select target
,选择要写入的目标microSD卡。
点击完成后会弹出选择目标,此时选择您通过读卡器插入电脑中的microSD卡。
选择完成后,会显示以下界面,点击Flash
后即可开始烧写。
如下图所示等待烧写完成即可。
使用Etcher烧写完成后,Windows可能会不知道如何读取您的microSD卡,会弹出如下图所示警告,点击取消
后拔出microSD卡即可。
3.9.2.3 启动SD卡系统
将下图中的拨码开关的boot0向下拨和boot1向上拨,使开发板进入SD卡启动模式。将SD卡插入开发板的卡槽中,步骤如下图所示:
使用两条Type-C线连接开发板端和电脑端,用于给开发板进行供电和使用串口登录开发板控制台。
使用串口软件查看串口控制台,成功启动后会进入开发板控制台。
3.10 使用wifi连接网络
3.10.1 结束开启联网脚本
安装启动开发板完成后,打开串口终端进入开发板控制台。由于开发板启动后会启动联网脚本,我们第一次配网时需要手动结束联网脚本。输入ps
,查看进程,找到下面所示的两个进程。
159 root 0:00 wpa_supplicant -D nl80211 -i wlan0 -c /etc/wpa_supplicant.178 root 0:00 udhcpc -R -n -p /var/run/udhcpc.eth0.pid -i eth0 -b
通过上述信息可以发现,我们需要手动结束159和178这两个进程,您的进程号可能和我不一致,按您开发板上世纪的进程操作。输入:
kill -9 <PID>
假设我使用的开发板中wpa_supplicant
和udhcpc
进程号分别为159和178,此时我应该输入以下命令
kill -9 159
kill -9 178
手动结束后使用ps
查看是否还存在对应进程。
3.10.2 填写WIFI信息
修改/etc/wpa_supplicant.conf
文件,填写wifi名称和密码,输入
vi /etc/wpa_supplicant.conf
进入vi
编辑器后会显示以下信息
ctrl_interface=/var/run/wpa_supplicant
update_config=1
ap_scan=1
在文件末尾增加网络信息
network={ssid="<wifi名称>"psk="<密码>"}
假设我的WiFi名称为Programmers,密码为123456,则实际添加的网络信息为:
network={ssid="Programmers"psk="12345678"}
添加完成后保存并退出vi编辑器。
3.10.3 连接WiFi
连接到 SSID,输入:
wpa_supplicant -B -iwlan0 -c /etc/wpa_supplicant.conf
执行完成后,如下所示
获取ip地址,输入:
udhcpc -i wlan0
获取完成后即为成功连接互联网。
测试WiFi是否可以访问互联网,输入ping www.baidu.com
,输入后如下所示:
[root@canaan ~ ]$ ping www.baidu.com
PING www.baidu.com (14.119.104.189): 56 data bytes
64 bytes from 14.119.104.189: seq=0 ttl=55 time=10.241 ms
64 bytes from 14.119.104.189: seq=1 ttl=55 time=16.292 ms
64 bytes from 14.119.104.189: seq=2 ttl=55 time=15.699 ms
64 bytes from 14.119.104.189: seq=3 ttl=55 time=12.508 ms
在后续启动开发板中,开发板会自动连接到SSID,您只需要重新获取ip地址即可访问互联网。
3.11 使用TFTP服务在Ubuntu和开发板传输文件
3.11.1 Ubuntu安装TFTP服务
在Ubuntu中执行以下命令安装TFTP服务:
sudo apt-get install tftp-hpa tftpd-hpa
然后,创建TFTP服务工作目录,并打开TFTP服务配置文件,如下:
mkdir -p /home/ubuntu/tftpboot
chmod 777 /home/ubuntu/tftpboot
sudo gedit /etc/default/tftpd-hpa
在配置文件/etc/default/tftpd-hpa中,将原来的内容删除,修改为:
TFTP_USERNAME="tftp"
TFTP_ADDRESS=":69"
TFTP_DIRECTORY="/home/ubuntu/tftpboot"
TFTP_OPTIONS="-l -c -s"
最后,重启TFTP服务:
sudo service tftpd-hpa restart
查看tftp服务是否在运行,运行如下命令,即可查看是否在后台运行。
ubuntu@ubuntu2004:~/Desktop$ ps -aux | grep “tftp”
ubuntu 4555 0.0 0.0 9040 652 pts/0 S+ 02:33 0:00 grep --color=auto “tftp”
3.11.2 开发板通过tftp传输文件
首先确保Ubuntu或Windows的tftp服务目录内,有需要下载到板子上的文件,比如:
ubuntu@ubuntu2004:~$ ls /home/ubuntu/tftpboot/
object_detect
确认Ubuntu的网络IP,例如
比如下载Ubuntu服务器下的zImage 文件,则在开发板上执行如下命令(Ubuntu的桥接网卡IP是192.168.0.197):
[root@canaan ~ ]$ tftp -g -r object_detect 192.168.0.197
下载过程如下所示:
[root@canaan ~ ]$ tftp -r object_detect -g 192.168.0.197
object_detect 100% |********************************| 894k 0:00:00 ETA
下载完成后,可以在当前目录找到该文件
[root@canaan ~ ]$ ls
data emmc object_detect
如何从开发板上传文件到Ubuntu?比如我们现在开发板家目录下创建一个1.txt 的文本文件,然后写入111111…. :
[root@100ask:~]$ tftp -p -l 1.txt 192.168.5.197
1.txt 100% |********************************| 8 0:00:00 ETA
此时我们查看Ubuntu服务器的tftp服务目录下,即可看到之前在开发板上创建的1.txt:
ubuntu@ubuntu2004:~$ ls /home/ubuntu/tftpboot/
1.txt object_detect
3.12 配置开发板SSH功能
3.12.1 修改ssh配置文件
使用Mobaxterm终端工具访问开发板的串口控制台,等待系统启动后,进入/etc/ssh
目录下
[root@canaan ~ ]$ cd /etc/ssh/
[root@canaan /etc/ssh ]$ ls
moduli ssh_config sshd_config
进入ssh目录可以看到有三个文件,您需要修改sshd_config
,使用vi命令进行修改
[root@canaan /etc/ssh ]$ vi sshd_config
输入后,进入vi编辑器,修改下图中红框处的两项。
配置SSH登录设置
将红框处两项取消注释,并将参数设置为yes
PermitRootLogin yes
PermitEmptyPasswords yes
修改完成后如下所示:
配置SFTP服务
修改sshd_config
中的sftp配置项
修改前:
Subsystem sftp /usr/libexec/sftp-server
修改后:
Subsystem sftp internal-sftp
修改完成后,按下esc
,输入:wq
,保存并退出编辑器。
3.12.2 启动ssh
当您修改完成配置文件后后,需要手动重启ssh,在终端输入/etc/init.d/S50sshd restart
。
[root@canaan ~ ]$ /etc/init.d/S50sshd restart
Stopping sshd: killall: sshd: no process killed
OK
Starting sshd: OK
输入完成后,ssh会重新启动。
3.12.3 连接ssh
开始前请注意:
- 您的PC电脑需要和开发板连接同一个WIFI。
在开发板串口终端输入udhcpc -i wlan0
,获取您的开发板连接WIFI的IP地址
[root@canaan ~ ]$ udhcpc -i wlan0
udhcpc: started, v1.31.1
udhcpc: sending discover
udhcpc: sending select for 192.168.0.154
udhcpc: lease of 192.168.0.154 obtained, lease time 122
deleting routers
adding dns 192.168.0.1
adding dns 192.168.0.1
获取完成后,输入ifconfig wlan0
,查看开发板所连接WIFI的IP地址
[root@canaan ~ ]$ ifconfig wlan0
wlan0 Link encap:Ethernet HWaddr 8C:F7:10:47:9B:6Einet addr:192.168.0.154 Bcast:192.168.0.255 Mask:255.255.255.0inet6 addr: fe80::8ef7:10ff:fe47:9b6e/64 Scope:LinkUP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1RX packets:438 errors:0 dropped:2 overruns:0 frame:0TX packets:21 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000RX bytes:34571 (33.7 KiB) TX bytes:2446 (2.3 KiB)
可以看到wlan0选项中的IP地址为:192.168.0.154
3.12.4 使用MobaXterm传输文件
使用MobaXterm终端工具,点击会话Session
,如下图中红框所示
点击完成后会弹出以下界面,点击使用SSH
,如下图红框所示:
进入ssh
配置界面后,远程主机Remote host
的框输入开发板的IP地址,勾选指定用户名Specify username
前的框,在后面填写开发板的用户名root
,填写完成后,点击OK即可。如下图所示
点击完成后就会打开一个新的终端,如下图所示:
您可以看到这里也可以访问开发的串口终端。您可以看到左边选项卡中的开发板对应的文件系统,例如data/emmc
,您在选项卡中可以对文件夹中内容进行下载或者上传。如下图所示,这里我进入/root/emmc/p3/app/ai/exe/
目录中,选择face_detect
文件,单击右键后弹出选项栏,选择Download即可开始下载该文件。
如果您想上传文件到当前目录,在左侧选项卡的空白处,点击右键,选择Upload to current folder
上传到当前文件夹即可。
4.系统功能及AI应用初体验
4.1 系统功能体验指南
4.1.1 ai demo程序
说明
nncase 的demo程序源码位于SDK目录下的package/ai
目录,目录结构如下:
$ tree -L 2 ai
ai
├── ai.hash
├── ai.mk
├── code
│ ├── build.sh
│ ├── cmake
│ ├── CMakeLists.txt
│ ├── common
│ ├── face_alignment
│ ├── face_detect
│ ├── face_expression
│ ├── face_landmarks
│ ├── face_recog
│ ├── hand_image_classify
│ ├── head_pose_estimation
│ ├── imx219_0.conf
│ ├── imx219_1.conf
│ ├── license_plate_recog
│ ├── object_detect
│ ├── object_detect_demo
│ ├── openpose
│ ├── person_detect
│ ├── retinaface_mb_320
│ ├── self_learning
│ ├── shell
│ ├── simple_pose
│ ├── video_192x320.conf
│ ├── video_object_detect_320.conf
│ ├── video_object_detect_320x320.conf
│ ├── video_object_detect_432x368.conf
│ ├── video_object_detect_512.conf
│ ├── video_object_detect_640.conf
│ └── video_object_detect_640x480.conf
└── Config.in
可以参考retinaface_mb_320的源码和CMakeLists.txt
添加新的nncase 的demo程序。
模型的编译参见nncase_demo.mk
里面定义的POST_INSTALL_TARGET_HOOKS:
NNCASE_DEMO_DEPENDENCIES += mediactl_lib nncase_linux_runtime opencv4 libdrm
define NNCASE_DEMO_COMPILE_MODELmkdir -p $(TARGET_DIR)/app/ai/kmodel/kmodel_compile/retinaface_mb_320cd $(@D) && /usr/bin/python3 retinaface_mb_320/rf_onnx.py --quant_type uint8 --model ai_kmodel_data/model_file/retinaface/retinaface_mobile0.25_320.onnxcp $(@D)/rf.kmodel $(TARGET_DIR)/app/ai/kmodel/kmodel_compile/retinaface_mb_320/rf_uint8.kmodelcd $(@D) && /usr/bin/python3 retinaface_mb_320/rf_onnx.py --quant_type bf16 --model ai_kmodel_data/model_file/retinaface/retinaface_mobile0.25_320.onnxcp $(@D)/rf.kmodel $(TARGET_DIR)/app/ai/kmodel/kmodel_compile/retinaface_mb_320/rf_bf16.kmodelNNCASE_DEMO_POST_INSTALL_TARGET_HOOKS += NNCASE_DEMO_COMPILE_MODEL
模型的编译需要nncase环境,关于nncase环境的搭建,参考k510_nncase_Developer_Guides.md。以后nncase有更新,buildroot sdk会同步更新到nncase。
retinaface
功能:人脸检测,人脸特征点检测
程序路径: /app/ai/shell
运行: 执行非量化模型,./retinaface_mb_320_bf16.sh
执行uint8量化模型,./retinaface_mb_320_uint8.sh
脚本里面有关于QOS的设置,下面的两个demo的设置一样。
#devmem phyaddr width value
devmem 0x970E00fc 32 0x0fffff00
devmem 0x970E0100 32 0x000000ff
devmem 0x970E00f4 32 0x00550000
跑demo时,需要优先保证屏幕显示正常,即调整显示相关的QoS为高优先级。 QOS_CTRL0.ax25mp write QoS = 5 QOS_CTRL0.ax25mp read QoS = 5 QOS_CTRL2.ispf2k write QoS = 0xf QOS_CTRL2.ispf2k read QoS = 0xf QOS_CTRL2.ispr2k write QoS = 0xf QOS_CTRL2.ispr2k read QoS = 0xf QOS_CTRL2.isp3dtof write QoS = 0xf QOS_CTRL3.display read QoS = 0xf QOS_CTRL3.display write QoS = 0xf
QOS 控制寄存器0(QOS_CTRL0) offset[0x00f4]
QOS 控制寄存器1(QOS_CTRL1) offset[0x00f8]
QOS 控制寄存器2(QOS_CTRL2) offset[0x00fc]
QOS 控制寄存器3(QOS_CTRL3) offset[0x0100]
模型的编译安装详见文件package/ai/ai.mk:
编译脚本路径: 100ask_base-aiApplication-demo/code/retinaface_mb_320/rf_onnx.py
object_detect
功能:物体分类检测,80分类
程序路径: /app/ai/shell
运行: 执行非量化模型,./object_detect_demo_bf16.sh
执行uint8量化模型,./object_detect_demo_uint8.sh
模型的编译安装详见文件package/ai/ai.mk
编译脚本路径: 100ask_base-aiApplication-demo/code/object_detect_demo/od_onnx.py
4.1.2 ffmpeg
ffmpeg
在ffmpeg-4.4
开源代码上进行移植,0001-buildroot-ffmpeg-0.1.patch
为补丁包,增加了
ff_k510_video_demuxer
:控制isp输入,引用了libvideo.so
ff_libk510_h264_encoder
:控制h264硬件编码,引用了libvenc.so
可以通过help指令查看可配置参数
ffmpeg -h encoder=libk510_h264 #查看k510编码器的参数
ffmpeg -h demuxer=libk510_video #查看demuxer的配置参数
详细运行说明参考K510_Multimedia_Developer_Guides.md
4.1.3 alsa_demo
alsa demo程序放在/app/alsa_demo
目录下:
运行准备:
- 插上耳机
使用ALSA UTILS测试。
4.1.4 TWOD demo
运行 rotation 使用方法:
cd /app/twod_app
./twod-rotation-app
将ouput.yuv 拷到yuv显示器上设置尺寸1080 x 1920,显示格式nv12,结果如下
scaler 使用方法
cd /app/twod_app
./twod-scaler-app
将ouput.yuv 拷到yuv显示器上设置尺寸640x480,显示格式nv12,结果如下
运行 rgb2yuv 使用方法:
cd /app/twod_app
./twod-osd2yuv-app
将ouput.yuv 拷到yuv 显示器上设置尺寸320x240,显示格式nv12,结果如下
运行 yuv2rgb 使用方法:
cd /app/twod_app
./twod-scaler-output-rgb888-app
将ouput.yuv 拷到rgb888显示器上设置尺寸640x480,显示格式rgb24,结果如下
运行 输出yuv上叠加osd 使用方法:
cd /app/twod_app
./twod-scaler-overlay-osd-app
将ouput.yuv 拷到显示器上设置尺寸640x480,显示格式nv12,结果如下
API:
/* 创建内存 */
twod_create_fb()
/* 配置原图片参数 */
twod_set_src_picture()
/* 配置输出图片参数 */
twod_set_des_picture()
/* 设置 scaler */
twod_set_scaler()
/* 等待操作完成 */
twod_wait_vsync()
/* Invali cache */
twod_InvalidateCache()
/* flash cache */
twod_flashdateCache()
/* 释放内存*/
twod_free_mem()
/* 设置旋转 */
twod_set_rot()
4.1.5 RTC demo
RTC驱动会注册生成/dev/rtc0设备节点。
应用层遵循Linux系统中的标准RTC编程方法调用驱动,在运行参考例程之前,建议通过shell 控制台关闭内核信息打印。
echo 0 > /proc/sys/kernel/printk
进入/app/rtc目录,输入如下命令启动rtc应用程序。
cd /app/rtc
./rtc 2021-11-3 21:10:59
程序的执行结果为:
RTC demo程序的主要代码片段如下,详细请参考package/rtc 文件夹下的代码。
/*解析参数,获取当前年月日、时分秒*/
if(argc !=3) {fprintf(stdout, "useage:\t ./rtc year-month-day hour:minute:second\n");fprintf(stdout, "example: ./rtc 2021-10-11 19:54:30\n");return -1;
}sscanf(argv[1], "%d-%d-%d", &year, &month, &day);
sscanf(argv[2], "%d:%d:%d", &hour, &minute, &second);/*打开RTC设备,设备节点是:/dev/rtc0 */
fd = open("/dev/rtc0", O_RDONLY);
if (fd == -1) {perror("/dev/rtc0");exit(errno);
}/* 设置RTC时间。*/
retval = ioctl(fd, RTC_SET_TIME, &rtc_tm);
if (retval == -1) {perror("ioctl");exit(errno);
}/* 休眠 2秒。 */
sleep(2);/* 读取RTC当前时间。*/
retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
if (retval == -1) {perror("ioctl");exit(errno);
}/* 打印 RTC当前时间。*/
fprintf(stdout, "\nRTC date/time: %d/%d/%d %02d:%02d:%02d\n",rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
4.1.6 WDT demo
K510一共有三个看门狗,WDT驱动会注册生成/dev/watchdog0、/dev/watchdog1、/dev/watchdog2 设备节点。
应用层遵循 Linux系统中的标准WDT编程方法调用驱动,wathdog应用程序第一个参数可为0、1,分别代表watchdog0、watchdog1,第二个参数表示可设置的超时时间(单位秒),例如如下命令表示启动watchdog0,watchdog0溢出时间40秒。
cd /app/watchdog
./watchdog 0 40
程序启动后将每间隔1秒喂一次看门狗,当shell终端中输入stop字符后,应用程序停止喂狗,看门狗将在设置超时时间溢出后复位设备重启,详细请参考package/watchdog文件夹下的代码。
程序的执行结果为:
注意:当前k510看门狗模块的工作时钟频率为757575Hz,以秒为单位的超时时间需要转换成看门狗实际的工作时钟频率的超时时间,计算公式是2^n/757575,因此实际的超时时间会大于等于输入的超时时间。
实际超时时间的计算过程是:
-
输入40,2^25/757575=44 > 40,2^24/757575=22 < 40,因此设置为44秒;
-
输入155,2^27/757575=177 > 155,因此设置为177秒;
-
输入2000,2^31/757575=2834 > 2000,因此设置为2834秒;
4.1.7 UART demo
K510一共有4个串口,当前驱动中串口2、3没有使能,串口0驱动会注册生成/dev/ttyS0设备节点。
应用层遵循Linux系统中的标准UART编程方法调用驱动。uart应用程序第一个参数可为0、1,分别代表uart0、uart1。
将开发板使用有线网连接到路由器,使得开发板和调试PC在一个网络中,当开发板上电后将自动获取IP,在开发板的shell串口终端中输入ifconfig命令获取IP地址,调试PC利用此IP通过telent连接开发板打开一个telent窗口。例如调试PC通过MobaXterm使用telent连接开发板的操作如下图。
telent终端窗口中输入如下命令启动串口0工作。
cd /app/uart
./uart 0
在telent窗口中输入要发送的内容,可以在shell串口终端窗口看到接收到的数据,详细请参考package/crb_demo/uart文件夹下的代码。
例如,telent窗口的输入:
对应的Shell串口终端窗口显示:
4.1.8 ETH demo
应用层遵循Linux系统中的标准ETH编程方法调用驱动。
Client
设备作为client端,进入/app/client目录,输入如下命令启动client应用程序,ETH应用程序第一个参数表示要建立TCP链接的服务器ip地址,例如输入如下命令表示启动ETH程序与10.20.5.1.13的server建立通信。
cd /app/client
./client 10.20.1.13
通过tcp协议连接server进行通信,在另一台ubuntu机器上运行server程序,详细代码请参考package/app/client文件夹下内容。
设备端显示日志:
Server
设备作为server端,进入/app/server目录,例如输入如下命令表示启动server程序。
cd /app/server
./server
在另一台ubuntu机器上运行client程序,通过tcp协议连接server进行通信,详细代码请参考package/crb_demo/server文件夹下内容。
设备端显示日志:
4.1.9 SDMMC demo
K510一共有3个SDMMC主控制器,开发板上SDMMC0用于接eMMC,SDMMC1用于WIFI模块,SDMMC2控制器用于接sdcard。
SDMMC驱动会注册生成/dev/mmcblk0,EMMC驱动会注册成/dev/mmcblk1设备节点。
SD卡在系统启动后会自动挂载到/root/data ,进入/app/write_read_file目录,SDMMC应用程序第一个参数表示要进行读写操作的文件,如SD卡挂载到/root/data,可对/root/data/目录下的文件进行读写操作,先写后读,输入如下命令启动SDMMC应用程序对SD卡进行读和写的操作并计算读写速度(单位m/s)。
cd /app/write_read_file
./write_read_file /root/data/test.txt
开启对SD卡进行1G数据的读写,代码请参考package/app/write_read_file文件夹下的内容。
4.1.10 SHA/AES demo
SHA/AES demo 使用Linux 内核导出 AF_ALG 类型的 Netlink 接口,在用户空间使用内核加密 API。详细信息请参考https://www.kernel.org/doc/html/latest/crypto/userspace-if.html。
参数:
-h 打印帮助信息
-t 算法类型:hash、skcipher
-n 算法名称:sha256、ecb(aes)、cbc(aes)
-x 解密操作
-k AES KEY(16进制字符串)
-v AES IV(16进制字符串)
sha256 test:
cd /app/crypto
echo -n "This is a test file, hello world" > plain.txt
./crypto -t hash -n "sha256" plain.txt sha256.txt
xxd -p -c 32 sha256.txt
sha256sum plain.txt
ecb(aes) 128 test:
cd /app/crypto
echo -n "This is a test file, hello world" > plain.txt
./crypto -t skcipher -n "ecb(aes)" -k 00112233445566778899aabbccddeeff plain.txt ecb_aes_en.bin
./crypto -t skcipher -n "ecb(aes)" -k 00112233445566778899aabbccddeeff -x ecb_aes_en.bin ecb_aes_de.bin
cmp ecb_aes_de.bin plain.txt
cat ecb_aes_de.bin
cbc(aes) 128 test
cd /app/crypto
echo -n "This is a test file, hello world" > plain.txt
./crypto -t skcipher -n "cbc(aes)" -k 00112233445566778899aabbccddeeff -v 00112233445566778899aabbccddeeff plain.txt cbc_aes_en.bin
./crypto -t skcipher -n "cbc(aes)" -k 00112233445566778899aabbccddeeff -v 00112233445566778899aabbccddeeff -x cbc_aes_en.bin cbc_aes_de.bin
cmp cbc_aes_de.bin plain.txt
cat cbc_aes_de.bin
aes-ecb-128和aes-cbc-128加密时要求明文要16字节对齐,不足会自动补0。
4.1.11 TRNG demo
TRNG demo通过读取/dev/hwrng字符设备产生指定长度的随机数,按16进制字符串输出。
./trng的输入参数含义:
-h 打印帮助信息
-b 指定输出随机数长度,单位byte
4.1.12 DRM demo
drm demo展示了VO硬件多图层功能。
VO共有8个layer:
-
背景层,可配置背景色。
-
layer0是video层,支持YUV422和YUV420,支持NV12和NV21格式,大小端可配,支持硬件scaling up和scaling down。
-
layer1-layer3是video层,支持YUV422和YUV420,支持NV12和NV21格式,大小端可配。
-
layer4-layer6是OSD层,支持多种ARGB格式。
开发板启动后进入/app/drm_demo目录,输入命令:
cd /app/drm_demo
./drm_demo
4.1.13 V4L2_DRM demo
v4l2_drm demo展示了摄像头输入和显示的功能。
开发板启动后进入/app/mediactl_lib目录,输入命令:
cd /app/mediactl_lib
./v4l2_drm.out -f video_drm_1080x1920.conf
或者
./v4l2_drm.out -f video_drm_1920x1080.conf
或者
./v4l2_drm.out -f imx385_video_1920x1080.conf
imx385 demo :
这个需要修改配置,具体参照 K510_V4l2_Developer_Guides.md,运行命令如下:
./v4l2_drm.out -f imx385_video_1920x1080.conf
启动v4l2_drm.out应用程序,v4l2_drm.out显示效果:
4.1.14 LVGL demo
进入/app/lvgl,运行以下命令:
cd /app/lvgl
./lvgl
显示效果如下:
4.1.15 PWM demo
PWM驱动会注册生成/sys/class/pwm/pwmchip0和/sys/class/pwm/pwmchip3设备节点。
本例程可分别对pwm0和pwm1进行配置和使能,进入/app/pwm目录,pwm应用程序第一个参数表示设置pwm的周期,单位为ns,第二个参数设置pwm一个周期中“ON”的时间,单位为ns,第三个参数可以为0、1,分别代表pwm0和pwm1,例如输入如下命令表示使能pwm0,周期为1s,占空比为1000000000/500000000*100% = 50%,详细代码请参考package/app/pwm文件夹下的内容。
cd /app/pwm
./pwm 1000000000 500000000 0
程序的执行结果为:
通过示波器连接K510 CRB5.1.2开发板J15的28号引脚,可以示波器上观察到一个周期为1秒,占空比为50%的波形图。
4.1.16 WIFI demo
WiFi模块驱动加载后会生成无线网卡wlan0,遵循标准网口驱动,正常参考TCP/IP socket编程。
-
在笔记本打开“移动热点”,然后设置热点的名称和密码
-
在笔记本上启动NetAssist,配置协议类型、本地主机IP、本地主机端口、接收设置、发送设置及需要发送的数据,如下图:
-
wifi测试程序的参数格式为:
./wifi <AP name> <password> <local ip> <server ip>
例如进入/app/wifi目录,输入启动wifi测试程序命令,程序的执行结果如下图:
4.1.17 GPIO_KEYS demo
按键驱动使用linux kernel自身集成的基于input子系统的通用gpio-keys驱动,驱动加载后在/dev/input目录下生成事件监控节点eventX,X为事件节点序号,可以通过cat /proc/bus/input/devices查看
gpio-keys例程阻塞式读取按键上报事件并打印事件信息,其信息包括按键编码和按键动作,按键编码标识按键身份,按键动作分为pressed和released,在按键release时例程会计算按键按下的持续时间
程序执行结果如下图所示:
4.2 AI应用体验指南
开发板系统中内置了丰富的AI应用示例程序,对每个示例程序我们都提供有对应的脚本文件,脚本文件中已经设置需要运行AI应用程序和对应的参数。
在开始演示AI应用指南前,需要确保您已经正确连接摄像头和显示屏并正常上电启动开发板。启动开发板后可以发现会自动运行摄像头获取图像并在显示屏上实时预览程序,需要手动结束该应用程序。使用方法如下:
-
输入
ps
查看应用程序查看进程号,例如实时预览程序进程端口号为189。189 root 0:01 ./v4l2_drm.out -f video_drm_1920x1080.conf -e 1 -s
-
输入
kill -9 <进程号>
,结束实时预览程序进程,例如我查看的端口号为189,则应该输入kill -9 189
结束实时预览程序后,显示屏会显示白屏,即代表成功结束摄像头获取图像并在显示屏上实时预览程序。
本章节介绍开发板内置的AI应用程序运行脚本都位于/app/ai/shell/
目录中。进入该目录,查看是否有对应脚本文件。
[root@canaan ~ ]$ cd /app/ai/shell/
[root@canaan /app/ai/shell ]$ ls
face_alignment.sh object_detect_demo_bf16.sh
face_detect.sh object_detect_demo_uint8.sh
face_expression.sh open_pose.sh
face_landmarks.sh person_detect.sh
face_recog.sh retinaface_mb_320_bf16.sh
hand_image_classify.sh retinaface_mb_320_uint8.sh
head_pose_estimation.sh self_learning.sh
license_recog.sh simple_pose.sh
object_detect.sh
下面介绍每个脚本对应的AI应用程序的运行指南,在进行以下演示时需要确保您的串口终端控制台已进入/app/ai/shell/
目录下。
4.2.1人脸对齐
人脸对齐,可得到图像或视频中的每个人脸估计出来的depth或者pncc信息。其中pncc信息为三维人脸形状上的顶点,不仅包含这一点的三维坐标信息,还包含此处的RGB取值。
论文链接:https://sci-hub.et-fine.com/10.1109/TPAMI.2017.2778152
将3D平均人脸的顶点坐标和RGB取值进行归一化操作,即NCC操作。如下图所示,下图取自论文中的截图。
Face Alignment 人脸对齐任务是基于一定量的训练集,得到一个模型,使得该模型对输入的一张任意姿态下的人脸图像能够进行特征点(landmark)标记。Face Alignment 任务一般的呈现方式是人脸特征点的检测与标记。
运行人脸对齐演示示例,在终端输入:
./face_alignment.sh
效果图如下所示:
4.2.2人脸检测
人脸检测采用了retina-face网络结构,backbone选取0.25-mobilenet。
论文链接:https://arxiv.org/pdf/1905.00641.pdf
GitHub链接:https://github.com/deepinsight/insightface
下图为单阶段逐像素密集人脸定位方法。
使用该应用时,可得到图像或视频中的每个人脸检测框以及每个人脸的左眼球/右眼球/鼻尖/左嘴角/右嘴角五个landmark。使用方法如下所示,输入:
./face_detect.sh
人脸检测器-bf16
执行非量化模型。使用方法如下所示,输入:
./retinaface_mb_320_bf16.sh
人脸检测器-uint8
执行uint8量化模型。使用方法如下所示,输入:
./retinaface_mb_320_uint8.sh
4.2.3人脸表情识别
人脸表情识别中需要用到两个模型一个模型用于检测人脸;一个模型用于进行人脸表情识别。人脸表情识别采用了人脸表情分类的方式,使用该应用可得到图像或视频中的每个人脸属于以下表情的概率。使用方法如下所示,输入:
./face_expression.sh
4.2.4人脸关键点检测
人脸关键点检测采用了PFLD(practical facial landmarks detection)。
论文链接:https://arxiv.org/pdf/1902.10859.pdf
使用该应用,可得到图像或视频中的每个人脸轮廓的106个关键点。使用方法如下所示,输入:
./face_landmarks.sh
4.2.5人脸识别
人脸识别采用了人脸特征提取后比对的方式,相同的人的特征会尽可能的像,而不同的人的特征则会有较大差距,使用该应用可得到图像或视频中的每个人脸与人脸底库中的人脸的相似度,以进行人脸识别任务。使用方法如下所示,输入:
./face_recog.sh
执行完成后会进入人脸检测模式,当摄像头检测到人脸后会,按下开发板的Key1,位置如下所示:
按下之后,可以在串口控制台中看到以下输出信息
>>>>> key code: 30, action: pressed <<<<<
total took 55.4448 ms
total took 56.2784 ms
Please Enter Your Name to Register:
>>>>> key code: 30, action: released <<<<<
上述输出信息提示您需要在串口终端输入人脸的登记名称,可直接输入录入人脸的信息,输入完成后按下回车即可。注意:目前登记信息仅支持英文输入。假设我这里输入登记名称为A,如下所示:
输入完成后会继续进入人脸检测模式,此时如果您刚刚登记的人脸再次被检测,则会在检测时标注出该人脸的登记信息。 您可重复进行登记人脸信息,登记后可以在人脸检测模式中进行人脸识别,区分登记不同信息的人脸。但当检测到没有登记的人脸信息则不会在检测时标注出人脸信息。
5.2.6人形检测
使用该应用时,可得到图像或视频中人体的检测框。使用方法如下所示,输入:
./person_detect.sh
人体关键点检测-openpose
人体关键点检测主要有两种检测方式,一个是自上而下,一种是自下而上。本应用采用了自下而上的模型openpose。使用该应用,可得到图像或视频中的每个人体的17个关键点。使用方法如下所示,输入:
./open_pose.sh
人体关键点检测-YOLOV5S
人体关键点检测主要有两种检测方式,一个是自上而下,一种是自下而上。本应用采用了自上而下的模型采用了YOLOV5S进行人体检测,然后使用simplepose进行关键点回归。使用该应用,可得到图像或视频中的每个人体的17个关键点。使用方法如下所示,输入:
./simple_pose.sh
4.2.7指尖指定区域识别
指尖指定区域识别主要包含3个流程,手掌检测+手掌关键点检测+图像识别。其中,手掌检测使用了512x512分辨率的 tiny-yolov3;手掌关键点检测使用了256x256分辨率的squeezenet1.1;图像识别使用了基于imagenet训练出来的mobilenetv2。通过手部关键点检测,利用两个食指尖,框定待识别区域。利用imagenet分类模型,确定待识别区域。使用方法如下所示,输入:
./hand_image_classify.sh
4.2.8头部态角估计
头部态角估计,可得到图像或视频中的每个人脸的roll/yaw/pitch。roll代表了人头歪的程度;yaw代表了人头左右旋转的程度;pitch代表了人头低头抬头的程度。使用方法如下所示,输入:
./head_pose_estimation.sh
4.2.9车牌识别
车牌识别的整体流程实际上包含了车牌检测+车牌识别两个流程。车牌检测采用了retinanet,车牌识别采用了lprnet。使用该应用,可得到图像或视频中的每个车牌的内容。使用方法如下所示,输入:
./license_recog.sh
4.2.10YOLOV5目标检测
目标检测采用了YOLOV5,使用该应用,可得到图像或视频中属于以下标签的目标的检测框。
"person", "bicycle", "car", "motorcycle", "airplane", "bus", "train", "truck",
"boat", "traffic light", "fire hydrant", "stop sign", "parking meter", "bench", "bird", "cat",
"dog", "horse", "sheep", "cow", "elephant", "bear", "zebra", "giraffe",
"backpack", "umbrella", "handbag", "tie", "suitcase", "frisbee", "skis", "snowboard",
"sports ball", "kite", "baseball bat", "baseball glove", "skateboard", "surfboard", "tennis racket", "bottle",
"wine glass", "cup", "fork", "knife", "spoon", "bowl", "banana", "apple",
"sandwich", "orange", "broccoli", "carrot", "hot dog", "pizza", "donut", "cake",
"chair", "couch", "potted plant", "bed", "dining table", "toilet", "tv", "laptop",
"mouse", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink",
"refrigerator", "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"
使用方法如下所示,输入:
./object_detect.sh
YOLOV5目标检测-bf16
执行非量化模型,使用方法如下所示,输入:
./object_detect_demo_bf16.sh
YOLOV5目标检测-uint8
执行uint8量化模型。使用方法如下所示,输入:
./object_detect_demo_uint8.sh
4.2.11自学习KNN算法
自学习借鉴的是KNN(k-Nearest Neighbors)的思想。该算法的思想是: 一个样本与数据集中的k个样本最相似, 如果这k个样本中的大多数属于某一个类别, 则该样本也属于这个类别。使用方法如下所示,输入:
./self_learning.sh
执行完成后会在显示屏上出现一个绿色的框。
该AI示例需要用到按键(Key 1)和按键(Key 2),两个按键的位置如下所示:
将需要识别的物体放在摄像头范围内,使该物体可以显示在绿色框中的正中间,此时需要手动标记按下Key1开始标记class0,按下Key1时会串口终端会提示以下信息:
>>>>> key code: 30, action: pressed <<<<<
Please press UP or DOWN button, UP: confirm, DOWN: switch!
>>>>> key code: 30, action: released <<<<<
上述信息为提示您,如果按下Key1则为标注图像,按下Key2则为切换模式。
继续按下Key1可开始自动标记该物体,此时串口终端会输出如下信息:
>>>>> key code: 30, action: pressed <<<<<
Pressed UP button!
class_0 : 1
>>>>> key code: 30, action: released <<<<<
此时再按下Key1会继续继续让您选择继续标注图像还是切换。
>>>>> key code: 30, action: pressed <<<<<
Please press UP or DOWN button, UP: confirm, DOWN: switch!
>>>>> key code: 30, action: released <<<<<
如果需要重复标记多次图像,可以继续按下Key1标记该物体。如下所示:
当标注完类别1(class 0)后按下Key2,串口终端会输出以下内容:
>>>>> key code: 48, action: released <<<<<
>>>>> key code: 48, action: pressed <<<<<
Pressed DOWN button!
switch to class_1
此时会切换标注类别1(class 1),继续按下Key 1进行标注类别1,选择功能。
>>>>> key code: 30, action: pressed <<<<<
Please press UP or DOWN button, UP: confirm, DOWN: switch!
>>>>> key code: 30, action: released <<<<<
继续按下Key 1标注类别1物体
>>>>> key code: 30, action: pressed <<<<<
Pressed UP button!
class_1 : 1
>>>>> key code: 30, action: released <<<<<
如果需要重复标记多次图像,可以继续按下Key1标记该物体,与上面类别0(class 0)标注方法一直。
在标注完成后,在不进入功能选择时,按下key 2结束标注,如下图所示。
>>>>> key code: 30, action: pressed <<<<<
Pressed UP button!
class_1 : 8
>>>>> key code: 30, action: released <<<<<
>>>>> key code: 48, action: released <<<<<
>>>>> key code: 48, action: pressed <<<<<
Pressed DOWN button!
Enter recog!
将刚才标注过的物体放在绿框内,此时会开发板会在显示屏上自动检测识别的物品,识别到物体时,左上角会显示对应物体的类别以及检测的精准度。
5.编写一个简单的helloword程序
5.1 编写helloword应用程序
打开Ubuntu虚拟机,打开终端进入Home目录中,新建helloword文件夹
ubuntu@ubuntu2004:~$ mkdir helloword
进入 helloword文件夹下,新建hello.c程序。
ubuntu@ubuntu2004:~$ cd helloword/
ubuntu@ubuntu2004:~/helloword$ touch helloword.c
在终端内gedit工具会打开一个 文本编辑器,进入文本编辑器内, 将helloword程序代码粘贴进去,粘贴完成后,直接按下 ctrl + s 保存,最后点击 右上角的 x 关 闭文本编辑器:
ubuntu@ubuntu2004:~/helloword$ gedit helloword.c
helloword程序代码:
#include <stdio.h>
int main (void)
{ printf("hello word!\n");return 0;
}
编写完成后,保存到 helloword.c 之后。我们需要指定存放交叉编译需要使用的库文件头文件的文件夹。如果需要在任意位置或者终端都可以使用交叉编译工具链,则需要单独 增加 工具链bin的路径至 ubuntu PATH环境变量里,可以添加至 ~/.bashrc
也可以在每一个终端单独配置。在终端执行以下命令:
export PATH=$PATH:~/100ask_base-aiApplication-demo/riscv64-buildroot-linux-gnu_sdk-buildroot/bin/
输入完成后,需要验证是否添加成功,在终端输入:
riscv64-linux-gcc -v
输入后可以正常打印gcc version 7.3.0 (2019-11-20_nds64le-linux-glibc-v5d-6c120106e03)
即可。
5.2.编写Makefile编译规则
ubuntu@ubuntu2004:~/helloword$ touch Makefile
ubuntu@ubuntu2004:~/helloword$ gedit Makefile
将下面的程序复制到Makefile文件中
CC := riscv64-linux-gcc
helloword: helloword.c${CC} -o helloword helloword.c
clean:rm helloword
填写完成后,按下Crtl+s保存Makefile文件。
5.3 交叉编译hellowrod程序
查看当前目录下是否存在helloword.c和Makefile:
ubuntu@ubuntu2004:~/helloword$ ls
helloword.c Makefile
确定文件存在后执行编译命令make
进行编译,如下所示:
ubuntu@ubuntu2004:~/helloword$ make
riscv64-linux-gcc -o helloword helloword.c
编译完成后会生成可执行文件hellword
。
可以执行 file hellword
命令 来查看编译出来的文件类型 是否是 riscv 架构类型。
ubuntu@ubuntu2004:~/helloword$ file helloword
helloword: ELF 64-bit LSB executable, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, for GNU/Linux 4.15.0, with debug_info, not stripped
5.2 上传程序到开发板上运行
把编译生成的 hello 文件通过 ssh或者TFTP拷贝到开发板上运行,这里使用TFTP传输,将生成的hello程序拷贝到tftpboot目录下:
ubuntu@ubuntu2004:~/helloword$ cp helloword /home/ubuntu/tftpboot
拷贝完成后,查看Ubuntu当前IP地址,输入ifconfig
后,获得IP地址为192.168.0.163
进入开发板的串口终端界面,获取tftpboot目录中helloword文件。
[root@canaan ~ ]$ tftp -g -r helloword 192.168.0.163
helloword 100% |********************************| 11680 0:00:00 ETA
为helloword程序增加可执行权限
[root@canaan ~ ]$ chmod 777 helloword
在开发板端执行helloword程序。
[root@canaan ~ ]$ ./helloword
hello word!
6.编译一个简单的AI demo程序
6.1 编译hello AI的demo程序
在任意目录中使用终端获取Hello AI的demo程序,输入以下命令获取
git clone https://e.coding.net/weidongshan/dongsahnpi-vision/100ask_hello-ai_demo.git
例如:
如果你无法下载,可访问百度网盘资料中的<开发板名称>/5_DongshanPI-Vision_嵌入式AI应用开发资料/2.Hello-AI_demo程序,该目录有demo程序压缩包,传入Ubuntu并解压即可。
下载完成后进入/home/ubuntu/100ask_base-aiApplication-demo/code
,新建hello_ai_demo
文件夹
ubuntu@ubuntu2004:~$ cd /home/ubuntu/100ask_base-aiApplication-demo/code/
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code$ mkdir hello_ai_demo
进入hello_ai_demo目录下,将获取Hello AI的demo程序拷贝到当前的hello_ai_demo目录下
cp /home/ubuntu/100ask_hello-ai_demo/* ./ -rf
拷贝完成后,可以看到hello-ai-demo文件夹下的文件如下所示:
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code/hello_ai_demo$ ls
CMakeFiles cv2_utils.cc format main.cc object_detect.h
cmake_install.cmake cv2_utils.h images Makefile README.md
CMakeLists.txt file include object_detect.cc
拷贝完成,返回上一级的code目录下,修改code目录下的CMakeLists.txt文件
ubuntu@ubuntu2004:~/ai_demo/100ask_base-aiApplication-demo/code/hello_ai_demo$ cd ../
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code$ gedit CMakeLists.txt
在文件末尾增加一句add_subdirectory(hello_ai_demo)
,修改后的CMakeLists.txt如下所示:
cmake_minimum_required(VERSION 3.2)
project(ai C CXX)#set(DEMO_ROOT "${PROJECT_SOURCE_DIR}/../crb_demo")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_C_FLAGS_RELEASE "-O2 -s")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")set(input imx219_1080x1920_0.conf imx219_0.conf imx219_1.conf video_192x320.conf video_object_detect_320.conf video_object_detect_432x368.conf video_object_detect_512.conf video_object_detect_640x480.conf video_object_detect_320x320.conf video_object_detect_480x640.conf video_object_detect_640.conf)
install(PROGRAMS ${input} DESTINATION exe)add_subdirectory(face_detect)
add_subdirectory(face_landmarks)
add_subdirectory(object_detect)
add_subdirectory(face_alignment)
add_subdirectory(face_expression)
add_subdirectory(head_pose_estimation)
add_subdirectory(face_recog)
add_subdirectory(simple_pose)
add_subdirectory(openpose)
add_subdirectory(person_detect)
add_subdirectory(hand_image_classify)
add_subdirectory(license_plate_recog)
add_subdirectory(self_learning)
add_subdirectory(object_detect_demo)
add_subdirectory(retinaface_mb_320)
add_subdirectory(hello_ai_demo)
修改完成后,按下Crtl+s
保存修改后的文件。
在code目录的终端下激活环境,输入:
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code$ source build.sh
激活环境完成,进入hello_ai_demo目录,开始进行编译Hello AI的demo程序
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code$ cd hello_ai_demo/
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code/hello_ai_demo$ make
编译完成,即可在hello_ai_demo目录下查看编译完成的可执行程序,如下图红框中所示文件:
6.2 上传程序到开发板运行
把编译生成的 hello 文件通过 ssh或者TFTP拷贝到开发板上运行,这里使用TFTP传输,将生成的hello_ai_demo程序拷贝到tftpboot目录下:
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code/hello_ai_demo$ cp hello_ai_demo ~/tftpboot/
将待检测的图像传入开发板,待测图像已经提前准备在hello_ai_demo目录下的images文件夹下
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code/hello_ai_demo$ cd images/
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code/hello_ai_demo/images$ ls
01_person.bmp 02_cat.bmp
将两张图像拷贝到tftpboot目录下:
ubuntu@ubuntu2004:~/100ask_base-aiApplication-demo/code/hello_ai_demo/images$ cp ./* ~/tftpboot/
拷贝完成后,查看Ubuntu当前IP地址,输入ifconfig
后,获得IP地址为192.168.0.163
进入开发板的串口终端界面,获取tftpboot目录中helloword文件。
[root@canaan ~ ]$ tftp -g -r hello_ai_demo 192.168.0.163
hello_ai_demo 100% |********************************| 818k 0:00:00 ETA
[root@canaan ~ ]$ tftp -g -r 01_person.bmp 192.168.0.163
01_person.bmp 100% |********************************| 300k 0:00:00 ETA
[root@canaan ~ ]$ tftp -g -r 02_cat.bmp 192.168.0.163
02_cat.bmp 100% |********************************| 300k 0:00:00 ETA
由于该程序需要使用模型文件对待测图像进行预测,我们可以拷贝开发板中模型文件使用
[root@canaan ~ ]$ cp /app/ai/kmodel/kmodel_release/object_detect/yolov5s_320/yol
ov5s_320_sigmoid_bf16_with_preprocess_output_nhwc.kmodel ./
拷贝完成后可以在当前目录看到对应文件。
[root@canaan ~ ]$ ls
01_person.bmp
02_cat.bmp
data
emmc
hello_ai_demo
yolov5s_320_sigmoid_bf16_with_preprocess_output_nhwc.kmodel
为hello_ai_demo程序增加可执行权限
[root@canaan ~ ]$ chmod 777 hello_ai_demo
在开发板端执行hello_ai_demo程序。
./hello_ai_demo ./yolov5s_320_sigmoid_bf16_with_preprocess_output_nhwc.kmodel ./01_person.bmp
执行结果如下所示:
例子1:
[root@canaan ~ ]$ ./hello_ai_demo ./yolov5s_320_sigmoid_bf16_with_preprocess_out
put_nhwc.kmodel ./01_person.bmp
hello 100ask AI demo!
==> run inference finished!
image inference result: person:0.89
程序识别出01_person.bmp文件中,有人,概率为0.89。
例子2:
[root@canaan ~ ]$ ./hello_ai_demo ./yolov5s_320_sigmoid_bf16_with_preprocess_out
put_nhwc.kmodel ./02_cat.bmp
hello 100ask AI demo!
==> run inference finished!
image inference result: cat:0.86
它识别出02_cat.bmp图片文件中,有猫,概率为0.86。
注意:您可以传入自定义的图像进行预测,需要保证图像格式为bmp,尺寸为320x320。
6.3 hello AI程序讲解
6.3.1 程序框架
6.3.2 程序讲解
从BMP文件提取RGB分量
int get_rgb_from_bmp(char *file, uint8_t *rbuf, uint8_t *gbuf, uint8_t *bbuf)
{ int err;unsigned int *p;unsigned int rgb32;int r_pos = 0, g_pos = 0, b_pos = 0;/* 点阵数据 */T_PixelDatas bmpPixelDatas;/* 解析BMP文件 */err = GetPixelDatasForIcon(file, &bmpPixelDatas);if (err){DebugPrint("Can not get digit bmp file: %s\n", file);return -1;}/* 把里面的RGB单独拆出来 */for (int y = 0; y < MIN(320, bmpPixelDatas.iHeight); y++){p = (unsigned int *)(bmpPixelDatas.aucPixelDatas + y * bmpPixelDatas.iLineBytes);r_pos = g_pos = b_pos = y*320;for (int x = 0; x < MIN(320, bmpPixelDatas.iWidth); x++){rgb32 = p[x];/*将RGB三通道的数据分别存入3个buf*/rbuf[r_pos++] = (rgb32 >> 16) & 0xff;gbuf[g_pos++] = (rgb32 >> 8) & 0xff;bbuf[b_pos++] = (rgb32 >> 0) & 0xff;}}return 0;}
初始化模型
objectDetect od(0.5, 0.45, 320, {320, 320});//置信度、nms阈值、模型尺寸、图像尺寸
od.load_model(argv[1]); //加载模型 yolov5s_320_sigmoid_bf16_with_preprocess_output_nhwc.kmodel
od.prepare_memory(); // memory allocation 准备内存
使用模型
/* 把RGB数据复制进od里 */od_r = (uint8_t *)od.virtual_addr_input[0]; od_g = od_r + 320*320;od_b = od_g + 320*320;memcpy(od_r, rbuf, 320*320);memcpy(od_g, gbuf, 320*320);memcpy(od_b, bbuf, 320*320);od.set_input(0);//设置输入od.set_output();//设施输出od.run();//运行推理od.get_output();//获得推理结果
后处理
/*后处理:将推理结果转换为可使用的数据*/std::vector<BoxInfo> result;od.post_process(result);//运行后处理 for (auto r : result){std::string text = od.labels[r.label] + ":" + std::to_string(round(r.score * 100) / 100.0).substr(0,4);cout<<"image inference result: ";cout<<text<<endl;}
7.嵌入式开发
7.1编译工具链
工具链是一组编程工具,用于开发软件、创建软件产品。工具链通常是另一个计算机程序或一组相关程序。通常,工具链里有多个工具,前一个工具的输出结果,是下一个工具的输入,也就是说前一个工具处理完,再交给下一个工具处理。
一个简单工具链可能由三部分组成:编译器和链接器(将源代码转换为可执行程序)、库(为操作系统提供接口)和调试器(用于测试和调试创建的程序)。一个复杂的软件产品,如视频游戏,需要准备音效、音乐、纹理、3 维模型和动画的工具,以及将这些资源组合成成品的附加工具。
**GNU ** 工具链 是一个广泛收集的、遵守GNU协议的、众多编程工具。这些工具形成一个工具链,用于开发应用程序和操作系统。
GNU 工具链在Linux、一些BSD系统和嵌入式系统软件的开发中起着至关重要的作用。
7.2 交叉编译工具链
**交叉编译器:**在平台A上使用它能够生成程序,这个程序时运行在平台B上的。例如,在PC上运行程序,但这个程序是在Android 智能手机上运行的,这个编译器就是交叉编译器。
在PC上为其他平台(目标平台)编译代码时,需要交叉编译器。能否直接在目标平台上编译程序?比如在ARM板上编译程序?大多时候不可行,因为ARM板资源很可能受限。
交叉编译器的基本用途是将构建环境与目标环境分开。这在几种情况下很有用:
-
设备资源极其有限的嵌入式计算机。例如,微波炉将有一个非常小的计算机来读取它的键盘和门传感器,向数字显示器和扬声器提供输出,并控制烹饪食物的机器。这台计算机通常不够强大,无法运行编译器、文件系统或开发环境。
-
为多目标编译。例如,公司可能希望用同一套代码,支持多个不同的操作系统。通过使用交叉编译器,可以设置单个构建环境,为每个目标系统单独编译程序。
-
在服务器上编译。服务器性能强大,很多公司都是在服务器上为其他平台编译程序。
-
引导到新平台。在为新平台开发软件时,人们使用交叉编译器来编译必要的工具,例如操作系统和本地编译器。
7.3 获得合适的交叉编译工具链
-
获取现成的
- 来自发行版系统内: Ubuntu 和 Debian 有许多现成的交叉编译器。
-
来自不同组织:
-
芯片原厂提供的交叉编译工具链(一般包含在配套的BSP内)。
-
Bootlin社区提供的各种架构工具链 。
-
ARM 官方提供的aarch32 aarch64工具链。
-
Linaro 提供 ARM 和 AArch64 工具链,以及一些早期版本工具链。
-
gnutoolchains 提供可以在windows上运行的交叉编译工具链。
-
riscv-collab 提供的riscv GNU 工具链。
-
-
自己编译构建
-
Crosstool-NG,专门构建交叉编译工具链的工具。 迄今为止拥有最可配置选项/并支持多种功能的。
-
嵌入式Linux构建系统一般都知道如何构建交叉编译工具链:Yocto/OpenEmbedded、Buildroot、OpenWRT等。
-
-
参考文档
-
Crosstool-NG 文档,https://github.com/crosstool-ng/crosstool-ng/blob/master/docs/
-
GCC 文档,https://gcc.gnu.org/onlinedocs/
-
Binutils 文档,https://sourceware.org/binutils/docs/
-
7.4 Makefile构建工具
7. 5 CMake构建工具
CMake 是一个开源的跨平台工具系列,旨在构建、测试和打包软件。 CMake 用于使用简单的平台和编译器独立配置文件来控制软件编译过程,并生成可在您选择的编译器环境中使用的本机 makefile 和工作区。 CMake 工具套件是由 Kitware 创建的,旨在响应 ITK 和 VTK 等开源项目对强大的跨平台构建环境的需求。
CMake 是 Kitware 的商业支持开源软件开发平台集合的一部分。
相关文章:
![](https://i-blog.csdnimg.cn/direct/dc17817a2ee4453cb4420a2aa07a9511.png)
嵌入式AI快速入门课程-K510篇 (第三篇 环境搭建及开发板操作)
第三篇 环境搭建及开发板操作 文章目录 第三篇 环境搭建及开发板操作1.配置VMware使用桥接网卡1.1 vmware设置1.2 虚拟网络编辑器设置 2.安装软件2.2 安装 Windows 软件2.3 使用MobaXterm远程登录Ubuntu2.4 使用FileZilla在Windows和Ubuntu之间传文件2.5编程示例:Ub…...
![](https://i-blog.csdnimg.cn/direct/67ec632b81eb47ab808f986a486706b7.png)
C++第三十九弹---C++ STL中的无序容器:unordered_set与unordered_map使用详解
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】 目录 1 unordered_set 1.1 unordered_set的接口说明 1.1.1 unordered_set的构造 1.1.2. unordered_set的容量 1.1.3. unordered_set的迭代器 1.1…...
![](https://i-blog.csdnimg.cn/direct/7c84988d066d48f8bb0a28f6fdacf402.png)
数学建模起步感受(赛前15天)
0基础直接上手数模,因为大一!年轻就是无所畏惧!开个玩笑,因为数模比赛比一年少一年… 抱着不打也是浪费的态度,我开始着手准备 首先python啥也不会,知道有元组这玩意… 仅仅在刷软考题的时候遇到python选择…...
![](https://i-blog.csdnimg.cn/direct/47e0ff4bd587435bb63c4c15fa689e3e.jpeg)
【YOLO5 项目实战】(4)红外目标检测
欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【YOLO5 项目实战】(1)YOLO5 环境配置与测试 【YOLO5 项目实战】(2)使用自己的数据集训练目标检测模型 【YOLO5 项目实战】(3)P…...
![](https://img-blog.csdnimg.cn/img_convert/99ce51fb8a37098737675699a746efd1.png)
游泳耳机哪个牌子好?角逐必选榜的4大王者游泳耳机测评解析!
在选择游泳耳机时,许多消费者往往会被市场上五花八门的产品所困扰。特别是那些标榜能够防水防潮的产品,但实际上它们往往缺乏核心技术支持,存在很高的损伤风险。据调查,超过90%的用户反映,市面上的游泳耳机常常无法达到…...
![](https://img-blog.csdnimg.cn/img_convert/b6a2be4cbee8f8183a3c1059d5436c44.png)
鹤岗房全国蔓延,现在要不要买房?
文|琥珀食酒社 作者 | 积溪 房子卖白菜价、人人都能买得起的时代 真的要来了 以前啊你花2万块钱 在大城市买不到一个厕所 可现在只要几万块你就能买一整套房 还带装修和家电 而且这样的房子还很多 “鹤岗”房已经在全国快速蔓延 那对咱普通人来说到底是好…...
![](https://i-blog.csdnimg.cn/direct/7023e986ee2745cba03efe67ddd9fcc7.png)
Flink程序部署与提交
前言 我们看门见山,生产环境一般用的是在YARN上面采用应用模式进行部署flink程序。实际生产中一般需要和资源管理平台(如YARN)结合起来,选择特定的模式来分配资源、部署应用。 部署模式 在一些应用场景中,对于集群资源分配和占用的方式,可能会有特定的需求。Flink 为各…...
![](https://i-blog.csdnimg.cn/direct/d09c1b8b79f14c828c8512248a7f6c8e.png)
了解Android
Android 系统架构 从图中可以看出,整个Android操作系统分为五层。它们分别是: 内核层 Android系统是基于Linux内核的,这一层为Android设备的各种硬件提供了底层的驱动。硬件抽象层 该层为硬件厂商定义了一套标准的接口。这样可以在不影响上层…...
![](https://i-blog.csdnimg.cn/direct/ed2632118bf64d818fcdbdfe421dcba9.png)
Tomcat学习进阶
目录 Apache Tomcat架构配置线程模型Tomcat 的类加载机制类加载器层次结构类加载流程 Tomcat 的优化策略Tomcat 的集群部署Tomcat故障排查 Apache Tomcat 架构配置 Apache Tomcat是一个开源的Java Servlet容器和Web服务器,它实现了Java EE规范中的Servlet和JSP API。…...
![](https://img-blog.csdnimg.cn/direct/b2e39275a06843c3b6c48d38a97a376e.jpeg)
【C++】————智能指针
作者主页: 作者主页 本篇博客专栏:C 创作时间 :2024年8月20日 一,什么是智能指针 在C中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露。解决这个问题最有效的方法是使用智能指针&…...
![](https://www.ngui.cc/images/no-images.jpg)
GT IP中CC序列(Clock Correction Sequence)的周期性
CC序列(Clock Correction Sequence),即时钟校正序列,在数字通信中扮演着至关重要的角色。这一序列的周期性插入机制,旨在确保发送器和接收器之间的时钟同步,从而维持数据传输的准确性和稳定性。以下是CC序列…...
![](https://www.ngui.cc/images/no-images.jpg)
grafana pod 无法启动 Only one datasource per organization can be marked as default
标题信息 helm 部署的 prometheus 全栈监控 chart 为 prometheus-community/kube-prometheus-stack helm 部署的 loki 日志系统 chart 为 grafana/loki-stack 问题描述 grafana pod 启动不了,查看该pod 日志报错如下 logger=provisioning t=2024-08-21T06:42:45.954318228…...
![](https://i-blog.csdnimg.cn/direct/5f4d4cd9bef343bcaa8fa64d876008e7.png)
你是如何克服编程学习中的挫折感的?(-@-^-0-)
在编程学习中遇到挫折感是极为常见且正常的现象,因为编程往往涉及解决复杂问题、理解抽象概念以及不断试错的过程。 以下是一些建议,帮助你在面对挫折时调整心态,继续前行: 接受失败是成长的一部分:首先要认识到&#…...
![](https://www.ngui.cc/images/no-images.jpg)
大数据技术之Zookeeper(1)
目录 Zookeeper 入门 概述 Zookeeper的主要特点包括: Zookeeper的应用场景: Zookeeper的基本概念: 架构: Zookeeper工作机制 Zookeeper数据结构 Znode(Zookeeper Node) Znode的类型 Znode路径 Znode属性 Wa…...
![](https://www.ngui.cc/images/no-images.jpg)
鸿蒙学习(四):泛型空安全模块导入导出
泛型与函数 泛型类型和函数允许创建的代码在各种类型上运行,而不仅支持单一类型。 泛型类和接口(Element) 类和接口可以定义为泛型,将参数添加到类型定义中,如以下示例中的类型参数Element: class CustomStack<Element>…...
![](https://www.ngui.cc/images/no-images.jpg)
无人机(Unmanned Aerial Vehicle, UAV)视觉感知论文汇总
综述类 A Survey of Object Detection for UAVs Based on Deep LearningDeep Learning for UAV-based Object Detection and Tracking:A surveyMoving Target Tracking by Unmanned Aerial Vehicle:A Survey and TaxonomyVision-Based Learning for Dro…...
![](https://www.ngui.cc/images/no-images.jpg)
【ORACLE】 ORA-01691: Lob 段无法通过 8192 (在表空间 XXX_SPACE 中) 扩展
ORA-01691错误通常表示Oracle数据库在尝试扩展LOB段时无法为表空间分配更多的空间。这个问题通常由表空间容量不足引起。根据搜索结果,以下是几种可能的解决方案: 检查并扩大表空间:首先,确认表空间是否已经达到其最大容量。可以使…...
![](https://www.ngui.cc/images/no-images.jpg)
Java之静态代理与动态代理的区别
🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主 📌 擅长领域:全栈工程师、爬虫、ACM算法 🔥 微信:zsqtcyw 联系我领取学习资料 …...
![](https://i-blog.csdnimg.cn/direct/0953dbe1d8d34770a34c1a46e9112d37.png)
公司内网监控软件有哪些?(2024年10款最新款推荐内网监控软件)
在2024年,公司内网监控软件市场提供了多种选择,以满足不同企业的监控需求。 以下是一些值得推荐的最新款内网监控软件: 1. Performance Monitor 核心功能:不仅是一款局域网监控软件,更是一个全面的内网安全管理解决方…...
![](https://www.ngui.cc/images/no-images.jpg)
CUDA编程07 - 卷积的优化
一:概述 在接下来的几篇文章中,我们将讨论一组重要的并行计算模式。这些模式是许多并行算法的基础,这些算法出现在许多并行应用中。我们将从卷积开始,卷积是一种流行的数组操作,广泛应用于信号处理、数字录音、图像处理、视频处理和计算机视觉等领域。在这些应用领域中,卷…...
![](https://img-blog.csdnimg.cn/img_convert/0be567da7425b78d78a24af0c969c5d5.jpeg)
解锁高效办公新姿势:SSO单点登录+企业网盘完美搭配
在现代互联网环境中,随着企业业务的不断扩展,多系统、多应用的集成成为常态。为了提升用户体验,减少用户在不同系统间切换的繁琐,单点登录(SSO, Single Sign-On)技术应运而生。 本文将详细介绍SSO单点登录的…...
![](https://i-blog.csdnimg.cn/direct/f35116a92fef49d581d9e8e9548e49a0.png)
[数据集][目标检测]竹子甘蔗发芽缺陷检测数据集VOC+YOLO格式2953张3类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2953 标注数量(xml文件个数):2953 标注数量(txt文件个数):2953 标注…...
![](https://i-blog.csdnimg.cn/direct/455ad69801034399b3e6b0c3ac566005.png)
RTC碰到LXTAL低频晶振停振怎么办?
GD32F303的RTC模块框图如下图所示,RTC时钟源可选择HXTAL/128、LXTAL或IRC40K,一般为了实现更精准的RTC时间,MCU系统均会外挂32.768KHz LXTAL低频晶振,但由于低频晶振负阻抗较大,不容易起振,若外部电路布线、…...
![](https://i-blog.csdnimg.cn/direct/5b8ff19cbb474532ab3340327cefcf50.png)
矩阵中的最大得分(Lc3148)——动态规划
给你一个由 正整数 组成、大小为 m x n 的矩阵 grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格(不必相邻)。从值为 c1 的单元格移动到值为 c2 的单元格的得分为 c2 - c1 。 你可以从 任一 单元格开始,并且必须…...
![](https://img-blog.csdnimg.cn/img_convert/550e585343b90c5c47ecc679906b21db.png)
C++ 设计模式(4. 建造者模式)
建造者模式(也被成为生成器模式),是一种创建型设计模式,软件开发过程中有的时候需要创建很复杂的对象,而建造者模式的主要思想是将对象的构建过程分为多个步骤,并为每个步骤定义一个抽象的接口。具体的构建…...
![](https://www.ngui.cc/images/no-images.jpg)
Arbitrum 和 Optimism Layer 2 扩展方案对比
Arbitrum 和 Optimism 对比分析 Arbitrum 和 Optimism 是两个以太坊 Layer 2 扩展方案,它们都使用了 Optimistic Rollup 技术来提升以太坊的可扩展性并降低交易成本。虽然它们有着相似的目标,但在架构设计、性能表现和费用结构上各有特点。 一、架构与…...
![](https://i-blog.csdnimg.cn/direct/b261eefbe8f14c7fbaa46433a900dce2.png)
热门的蓝牙耳机中,哪种类型更受欢迎?四款热度高的开放式耳机
在如今的耳机市场中,开放式耳机异军突起,成为了众多消费者的新宠。如果你还在为传统入耳式耳机带来的不适而烦恼,那么开放式耳机绝对值得你一试。它不仅能让你在享受音乐的同时,依然可以清晰感知周围环境,保障你的安全…...
![](https://www.ngui.cc/images/no-images.jpg)
基于web的亚热带常见自然林病虫害识别系统——总结与展望
文章目录 一、前言二、总结三、展望参考文献致谢一、前言 这个系列也迎来了结尾,最后说一些碎碎念… 二、总结 本文首先简要介绍了卷积神经网络的基本原理,以及在亚热带常见自然林植物识别领域的研究应用现状。 其重点研究了卷积神经网络在亚热带常见自然林植物叶片病害识…...
![](https://www.ngui.cc/images/no-images.jpg)
其他自动重试的注解
除了 Retryable 注解之外,Spring 提供了其他注解用于自动重试方法,主要包括以下几个注解: 1. Recover Recover 注解用于定义重试次数耗尽后执行的恢复方法。当 Retryable 注解的重试次数达到上限时,Recover 方法会被调用。这通常…...
![](https://img-blog.csdnimg.cn/direct/4ff52dec493642e09d0a26daa32dad38.jpeg)
宠物空气净化器哪款能吸毛?希喂、米家宠物空气净化器测评分享
养猫最令人困扰的,就是掉毛与难以彻底消除的异味,这两个问题就成了养猫生活中的一大挑战。每当换季或是猫咪自我梳理时,家中便被一层细腻的绒毛覆盖,从地板到沙发,从床单到衣物,甚至是空气中都漂浮着细小的…...
![](/images/no-images.jpg)
儿童编程网课平台哪个好/seo优化技术教程
AtomicReference类的getAndSet()方法用于以原子方式将AtomicReference对象的值设置为newValue,该值作为参数传递并返回AtomicReference对象的旧值,并具有由VarHandle.getAndSet(java.lang.Object ... ).VarHandle.getAndSet(java.lang.Object…)指定将变…...
![](/images/no-images.jpg)
有没有专门做奶粉的网站/快速排名工具免费查询
第一次被破坏 其实发生在双亲委派模型出现之前–即JDK1.2发布之前。由于双亲委派模型是在JDK1.2之后才被引入的,而类加载器和抽象类java.lang.ClassLoader则是JDK1.0时候就已经存在,面对已经存在 的用户自定义类加载器的实现代码,Java设计者…...
![](https://img-blog.csdnimg.cn/img_convert/5580deccc64e977604f3b48b7f594387.png)
网站的通栏怎么做/找百度
前言 回顾一下自己这段时间的经历,因公司突然通知裁员,我匆匆忙忙地出去面了几家,但最终都没有拿到offer,我感觉今年的寒冬有点冷。公司开始第二波裁员,我决定主动拿赔偿走人。后续的面试过程我做了一些准备ÿ…...
![](/images/no-images.jpg)
竹中建设官方网站/郑州百度推广开户
31-40题31、写一个交互脚本,直接运行脚本,出现提示,选择一个数字:1:重启 httpd 服务,2:重启 mysqld 服务 3:重启vsftpd服务,加选项--httpd重启 httpd 服务,加…...
![](https://img-blog.csdnimg.cn/a537936bc0fe45f1a202854a5ed411c9.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBATXJycl9MaQ==,size_20,color_FFFFFF,t_70,g_se,x_16)
北龙中网 可信网站验证 费用/网站优化是什么意思
内存屏障:Memory Barrier(Memory Fence) ● 可见性 ○ 写屏障(sfence)保证在该屏障之前的,对共享变量的改动,都同步到主存当中 ○ 而读屏障(lfence)保证在该屏障之后&…...
![](/images/no-images.jpg)
标签 wordpress/长春网站建设
摘要: C实现求解给定文本中以指定字符开头和结尾的子串数量的三种算法 难度: 初级。 一、 问题描述: 求解给定文本text 中以字符 A 开头, 字符B 结尾的子串数量。例如,文本ABCAAB 中以A开头B结尾的子串分别为…...