K210物体检测(利用Maixpy、在线模型训练、串口通信)
无论从性能还是价格上,K210都给我带来了很多惊喜。搭载了Maixpy的K210开发非常便利,加上Maixhub的加持,使得K210的生态更加完善。Maixpy完全兼容openmv,在拥有openmv的基础上,短时间内就可以上手K210。
目录
前言
硬件:亚博智能 K210 Developer Kit
开发环境:Maixpy
K210有两种常见的开发方式,C++和python。C++开发能最大限度发挥K210性能,缺点是要基于一个繁琐的SDK开发。我选择python开发并不是因为人生苦短,主要是被maixpy的生态吸引了。我手上的开发板是亚博智能的K210,需要烧固件才能用maixpy。本文将利用Maixhub的在线训练进行模型训练,再使用K210进行物体检测,最后利用串口发送识别信息。
一、烧Maixpy固件
固件下载地址https://dl.sipeed.com/
在搜索栏搜索support bin,下载最新固件即可。固件有几种类型:openmv_kmodel_v4_with_ide_support.bin、minimum_with_kmodel_v4_support.bin、minimum_speech_with_ide_support.bin、minimum_with_ide_support.bin,选择第一种,支持openmv和IDE的固件。
然后还要下载烧固件的软件,搜索kflash,如果是windows选择第三个下载。
运行kflash,将固件烧写到地址0x00000,其他默认,点击下载。0x00000是程序的起始地址。
打开Maixpy IDE,选择对应的开发板,亚博的需要选最后一个。点击连接并运行hello world进行测试。
二、制作数据集并训练
以下内容基于这个链接。
https://www.maixhub.com/ModelTrainingHelp_zh.html#maixhub-%E6%A8%A1%E5%9E%8B%E8%AE%AD%E7%BB%83%E5%B9%B3%E5%8F%B0%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
训练方式有两种,本地训练和在线训练。本地训练需要搭环境,在线训练按照要求上传数据集即可。对于K210的轻量模型,使用在线训练时间一般在30min之内,这个速度还可以接受。在maixhub上面有很多开源的模型,https://www.maixhub.com/一个很有潜力的社区,这是吸引我用maixpy开发的主要原因。
1.采集图片
直接使用K210采集是最好的方案,maixhub模型训练规定图片像素为224X224。官方很贴心的给出了一个采集图片的脚本,只需把脚本放进SD即可。由于我使用的是亚博的K210,需要对脚本做一些修改。
取消注释:
sensor.set_hmirror(True) # 上下翻转
sensor.set_vflip(True) # 左右翻转
LCD初始化改为:
lcd.init(invert=1, freq=15000000)
lcd.rotation(2)
'''
1.根据您的硬件(如lcd)更改摄像头和lcd配置
2.准备一张支持SPI模式的SD卡,并使用MBR(msdos)分区格式化为FAT32
3.复制到SD卡根目录
4.关闭主板电源,然后将SD卡插入主板
5.打开电源,它会自动创建一个类似“cap_images_1”的目录,下一次将是“cap_images_2”,以避免重写
6.按下板上的“启动”按钮并释放以捕获一张图像,这会将图像保存为“cap_images_1/0/0”。jpg`,
7.长按“boot”按钮切换等级,这将创建一个新目录,如“cap_images_1/1/”,稍后捕获的图像将保存到此目录,如“cap_images_1/1/0”。jpg`
8.关机,弹出SD卡,安装到电脑上,现在你可以在文件浏览器中看到你的图像了
'''
import sensor, lcd
from Maix import GPIO
from fpioa_manager import fm
from board import board_info
import os, sys
import time
import image
#### image size #### 规定图片像素为224X224
set_windowing = (224, 224)
#### sensor config ####
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA) # 320x240
try:
sensor.set_jb_quality(95) # for IDE display quality
except Exception:
pass # no IDE support
if set_windowing:
sensor.set_windowing(set_windowing)
# sensor.set_auto_gain(False)
# sensor.set_auto_whitebal(False, rgb_gain_db=(0x52,0x40,0x4d))
# sensor.set_saturation(0)
# sensor.set_brightness(4)
# sensor.set_contrast(0)
sensor.set_hmirror(True) # 上下翻转
sensor.set_vflip(True) # 左右翻转
# sensor.set_auto_whitebal(False)
sensor.skip_frames() #丢弃前面的帧
#### lcd config ####
lcd.init(invert=1, freq=15000000)
lcd.rotation(2)
#### boot key ####
boot_pin = 2 # board_info.BOOT_KEY
fm.register(boot_pin, fm.fpioa.GPIOHS0)
key = GPIO(GPIO.GPIOHS0, GPIO.PULL_UP)
######################################################
以下代码与官方相同
2.图片标注
使用labelimg进行标注,https://github.com/tzutalin/labelImg/releases,导入图片文件夹,设置标签,框出物体,保存xml文件即可。根据要求需要对导出数据进行整理,
上图是官方给出的两种整理方式,实测多个物体时第二种会报错。实际上无论单物体还是多物体都可以直接采用第一种目录,将所有图片放到images,所有标签放入xml。最后要在images和xml目录下建一个labels.txt,里面每隔一行填写一个标签。
3.在线训练模型
https://www.maixhub.com/ModelTraining
根据链接,获取机器码,填写相关信息,上传模型,然后开始训练。有两种训练方式,物体分类和物体检测,物体检测会输出坐标并框出物体,物体分类只会返回物体标签。如果刷新界面后如果一直停留在1%,就是数据集有误,根据Message输出的错误信息修改。
三、将模型部署到K210
下载训练好的模型,会得到如下目录。
boot.py是跑这个模型的例程,根据不同的开发板对boot.py进行修改,主要是显示方向和LCD配置。然后把所有文件放到SD卡根目录,上电即可跑模型。
另一种方式是烧到flash里,把m.kmodel用KFlash烧到0x300000以后的地址。K210是没有内部Flash的,程序只能从SRAM、外部Flash或SD卡启动。0x00000是程序启动的首地址,前面我们在0x00000烧了maixpy的固件,也就是K210会首先跑固件然后才会跑我们的程序。在0x300000烧模型,意味着我们预留了3M的空间给固件和主程序,在主程序中通过寻址0x300000即可导入模型。这里m.kmodel的大小是1.8M,也就是在0x500000可以烧其他模型。
这时需要使用Maixpy IDE烧录boot.py,在Flash运行需要对boot.py做以下修改:
#拉到最下面
main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)
简单跑一个数字识别,效果还行,有20几帧。
四、串口通信
K210的IO空需要自己指定功能映射后才能使用,有点像FPGA。内部分为8个GPIO和32个高速GPIO,全部都需要映射后才能使用。
一个简单的点灯:硬件上IO0连接了LED,需要把0与任意的GPIO或者高速GPIO进行映射(不一定是GPIO0),然后再操作这个GPIO。
fm.register(0, fm.fpioa.GPIO0, force=True)
LED_R = GPIO(GPIO.GPIO0, GPIO.OUT,value=1) #构建 LED 对象
LED_R.value(0) #低电平点亮
下面是串口通信:K210一共有3个串口,UART1-3,实际上还有一个是ISP的串口,用来下载程序。
ISP这个串口也可以用来通信,但是不需要进行映射,直接用print就可以了。串口1-3需要进行映射,下面把串口1映射到IO9和IO10。
fm.register(9, fm.fpioa.UART1_TX, force=True)
fm.register(10, fm.fpioa.UART1_RX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 1, 0, timeout=1000, read_buf_len=4096)
使用uart_A.write()和uart_A.read()进行发送和接收。这时候用杜邦线连接IO9和IO10就可以与其他单片机进行通信了。
Maixhub的物体检测基于yolov2,检测到的物体会返回坐标返回在物体上画一个方框,利用这个返回的坐标就可以判断物体在什么位置,左边还是右边。
结语
K210算力是0.8TOPS,比树莓派4B和Jetson Nano都要高。但是有一个局限性,内存只有6M。意味着只能跑简单的模型,模型一大内存就跑满了。
来源:微光feng