MaixHub是MaixPy官方提供的在线训练k210模型的平台(目前只支持YOLOv2的模型),MaixHub可以在线训练模型,在本地只需要上传训练集数据(需限制大小为20M以下),等待云端训练完成就能下载到训练好的模型。下面为制作训练集的步骤。
MaixPy 是将 Micropython 移植到 K210(一款 64 位双核带硬件 FPU、卷积加速器、FFT、Sha256 的 RISC-V CPU ) 的一个项目; MaixPy 不但支持 MCU 常规操作, 还集成了硬件加速的
AI
机器视觉和麦克风阵列相关的算法。相应的高达1TOPS
算力核心模块却不到¥50
, 凭借着快速开发和较低成本与其较小的体积很适合AIOT
领域智能应用。
1.图片采集及预处理
使用手机等拍照设备采集
这种方式采集到的图片可能不是 224x224
分辨率,可以使用Image_tool软件(下载)自动裁剪,在Image_tool中选中需要处理的图片目录即可,Image_tool会自动裁剪出中心的物体,输出格式为224x244
的图像。
使用k210开发版采集
在k210中执行下面拍照功能的脚本 ,用k210作为相机,这样获取的图片为224x224
不需要做预处理
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 ####
set_windowing = (224, 224)
#### sensor config ####
sensor.reset(freq=22000000, dual_buff=False)
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) # image horizonal mirror
# sensor.set_vflip(True) # image vertical flip
# sensor.set_auto_whitebal(False)
sensor.skip_frames()
#### lcd config ####
lcd.init(type=1, freq=15000000)
lcd.rotation(2)
#### boot key ####
boot_pin = 16 # board_info.BOOT_KEY
fm.register(boot_pin, fm.fpioa.GPIOHS0)
key = GPIO(GPIO.GPIOHS0, GPIO.PULL_UP)
######################################################
#### main ####
def capture_main(key):
def draw_string(img, x, y, text, color, scale, bg=None , full_w = False):
if bg:
if full_w:
full_w = img.width()
else:
full_w = len(text)*8*scale+4
img.draw_rectangle(x-2,y-2, full_w, 16*scale, fill=True, color=bg)
img = img.draw_string(x, y, text, color=color,scale=scale)
return img
def del_all_images():
os.chdir("/sd")
images_dir = "cap_images"
if images_dir in os.listdir():
os.chdir(images_dir)
types = os.listdir()
for t in types:
os.chdir(t)
files = os.listdir()
for f in files:
os.remove(f)
os.chdir("..")
os.rmdir(t)
os.chdir("..")
os.rmdir(images_dir)
# del_all_images()
os.chdir("/sd")
dirs = os.listdir()
images_dir = "cap_images"
last_dir = 0
for d in dirs:
if d.startswith(images_dir):
if len(d) > 11:
n = int(d[11:])
if n > last_dir:
last_dir = n
images_dir = "{}_{}".format(images_dir, last_dir+1)
print("save to ", images_dir)
if images_dir in os.listdir():
img = image.Image()
img = draw_string(img, 2, 200, "please del cap_images dir", color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
sys.exit(1)
os.mkdir(images_dir)
last_cap_time = 0
last_btn_status = 1
save_dir = 0
save_count = 0
os.mkdir("{}/{}".format(images_dir, save_dir))
while(True):
img0 = sensor.snapshot()
if set_windowing:
img = image.Image()
img = img.draw_image(img0, (img.width() - set_windowing[0])//2, img.height() - set_windowing[1])
else:
img = img0.copy()
# img = img.resize(320, 240)
if key.value() == 0:
time.sleep_ms(30)
if key.value() == 0 and (last_btn_status == 1) and (time.ticks_ms() - last_cap_time > 500):
last_btn_status = 0
last_cap_time = time.ticks_ms()
else:
if time.ticks_ms() - last_cap_time > 5000:
img = draw_string(img, 2, 200, "release to change type", color=lcd.WHITE,scale=1, bg=lcd.RED)
else:
img = draw_string(img, 2, 200, "release to capture", color=lcd.WHITE,scale=1, bg=lcd.RED)
if time.ticks_ms() - last_cap_time > 2000:
img = draw_string(img, 2, 160, "keep push to change type", color=lcd.WHITE,scale=1, bg=lcd.RED)
else:
time.sleep_ms(30)
if key.value() == 1 and (last_btn_status == 0):
if time.ticks_ms() - last_cap_time > 5000:
img = draw_string(img, 2, 200, "change object type", color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
time.sleep_ms(1000)
save_dir += 1
save_count = 0
dir_name = "{}/{}".format(images_dir, save_dir)
os.mkdir(dir_name)
else:
draw_string(img, 2, 200, "capture image {}".format(save_count), color=lcd.WHITE,scale=1, bg=lcd.RED)
lcd.display(img)
f_name = "{}/{}/{}.jpg".format(images_dir, save_dir, save_count)
img0.save(f_name, quality=95)
save_count += 1
last_btn_status = 1
img = draw_string(img, 2, 0, "will save to {}/{}/{}.jpg".format(images_dir, save_dir, save_count), color=lcd.WHITE,scale=1, bg=lcd.RED, full_w=True)
lcd.display(img)
del img
del img0
def main():
try:
capture_main(key)
except Exception as e:
print("error:", e)
import uio
s = uio.StringIO()
sys.print_exception(e, s)
s = s.getvalue()
img = image.Image()
img.draw_string(0, 0, s)
lcd.display(img)
main()
2.标注数据集
maixhub提供两种模型类别
- 物体分类:区分物体的类别,无位置检测
- 物体检测:检测物体的位置,不进行分类
这里使用的是物体检测,可以使用labelImg工具(下载)进行标注,注意最终要生成下面的目录结构,每个xml文件与images文件一一对应。
----images
| |
| |---0.jpg
| |
| ---1.jpg
|
------xml
|---0.xml
|
|---1.xml
或者两级目录
images
|
----ball
| |
| ---0.jpg
| |
| ---1.jpg
|
----toy
| |
| ---0.jpg
---pic0.jpg
xml
|
----ball
| |
| ---0.xml
| |
| ---1.xml
|
----toy
| |
| ---0.xml
----pic0.xml
标记图片过程演示,Open Dir 选中images目录下要标记的图片所在目录,Change Save Dir选中对应xml目录下与上步要标记图片目录同名的目录(没有的话就创建),用快捷键W
绘制识别区域并选一个标签,D
切换下一张图片。
【注意】:操作的路径不能有中文
【tips】:labelImg可以配置成自动保存,使用W键绘制区域,D键切换下一张图片
3.打包数据集
把上面的图片和标签按下面结构打包成zip文件,单级别目录结构
datasets.zip
|
datasets
|
----images
| |
| |---0.jpg
| |
| ---1.jpg
|
|------xml
| |---0.xml
| |
| |---1.xml
----labels.txt
或者两级目录结构
datasets.zip
|
datasets
|
|---images
| |
| ----ball
| | |
| | ---0.jpg
| | |
| | ---1.jpg
| |
| ----toy
| | |
| | ---0.jpg
| ---pic0.jpg
|---xml
| |
| ----ball
| | |
| | ---0.xml
| | |
| | ---1.xml
| |
| ----toy
| | |
| | ---0.xml
| ----pic0.xml
--labels.txt
其中的labels.txt存放分类的标签
left
right
stop
straight
4.上传数据集进行训练
到 https://www.maixhub.com/mtrain.html 创建训练任务,其中机器码的获取方式(传送门)
上传数据集时需要选中上面步骤中做好的zip文件,然后提交训练任务即可
5.运行模型
模型训练好之后可以在个人中心下载到文件包
文件包内的文件说明:
- boot.py: 在 maixpy 上运行的代码
- .kmodel 或者 .smodel: 训练好的模型文件( smodel 是加密模型 )
- labels.txt: 分类标签
- startup.jpg: 启动图标
- report.jpg: 训练报告,包括了损失和准确度报告等
- warning.txt: 训练警告信息,如果有这个文件,务必阅读, 里面的原因可能会导致训练精度低
使用方法:
- 按照文档(maixpy.sipeed.com)更新到最新的固件
如果新固件出现bug,可以使用这个固件测试(选择minimum_with_ide_support.bin):
https://api.dl.sipeed.com/shareURL/MAIX/MaixPy/release/master/maixpy_v0.6.0_2_g9720594 - 准备一张 SD 卡, 将本目录下的文件拷贝到 SD 卡根目录
- SD 卡插入开发板
- 开发板上电启动
- 摄像头对准训练的物体,
屏幕左上角会显示 物体标签 和 概率
屏幕左下角会显示 运行模型消耗的时间,单位是毫秒
Comments | NOTHING