硬件平台:K210 Sipeed Maix Dock

软件平台:maixpy

实现功能:自学习分类,无需在pc上训练分类,在K210上就可以

实现步骤

一、下载固件

maixpy固件

其中,各文件说明如下:

一般就下载第一个 maixpy_*.bin文件,功能比较全,但文件比较大,看单片机Flash使用情况而定。

得到bin文件后 直接打开kflash 烧录进板子里 注意地址为:0X00000

二、下载模型

打开 maixhub 找到模型文件,输入机器码下载。(如何获取机器码 参考往期的博客。)

(最好每次都通过 keygen.bin的固件通过串口发一次机器码,因为 今天用手动输入的机器码 会导致模型运行的时候无法解密出现报错“[MAIXPY]kpu: load error:2002, ERR_KMODEL_VERSION: only support kmodel V3/V4 now”)

这里有两个模型, 其中较大的模型有 1.8MiB, lite 版本只有 800KiB, lite 版本在使用时初始化代码需要添加fea_len参数为512, 较大模型不需要设置这个参数:

classifier = kpu.classifier(model, class_num, sample_num, fea_len=512)
  • 注意模型烧录地址, 和加载地址,不要弄错了,比如代码model = kpu.load(0x300000)则需要使用 kflash_gui 烧录模型到 0x300000
  • 注意上面说的 lite 模型需要设置 fea_len 参数
  • MaixPy 固件版本应该至少大于 maixpy_v0.6.2_46_geafab8cfd (提交 eafab8cfdfe0aa233586b17d8bc72a266d1b2b61)

三、脚本

包含示例脚本和加载脚本

①示例脚本 self_learning_classifier.py

需要自行修改 board_info 。方法:在官网资料中找到对应板子的 config_*.py文件,进入IDE中运行,即可以完成对板子的配置项(config.json)的导入,它会在flash上存储该配置文件。

运行配置代码后会自动重启,此时代码中才可以调用 board_info.BOOT_KEY , 实际上 board_info.BOOT_KEY 就是指 IO 16 ,对应的定义在 config.json 中可以得知,如果不存在的资源将会报错,如没有 LED 定义的硬件,运行 LED 点亮的时候就会报错“[Warning] Not loaded from /flash/config.json to board_info”。

下面是示例脚本代码

在IDE运行示例脚本后,按开发板上的 boot 按钮 来捕获 3 个类别 如:手机, 小车, 键盘, 每个类别只需要捕获一次
然后捕获 15 张图, 对顺序没有要求, 比如捕获 5 张 手机, 5 张 小车 , 5 张 键盘 的图片
然后它会自动学习这 15 张图的特征
最后识别到的图像类别会展示在左上角

import KPU as kpu
import sensor
import lcd
from Maix import GPIO,utils
from fpioa_manager import fm
#from board import board_info
import time
import gc############### config #################
class_num = 3
sample_num = 15
THRESHOLD = 11
class_names = ['class1', 'class2', 'class3']
board_cube = 0
########################################def draw_string(img, x, y, text, color, scale, bg=None ):if bg:img.draw_rectangle(x-2,y-2, len(text)*8*scale+4 , 16*scale, fill=True, color=bg)img = img.draw_string(x, y, text, color=color,scale=scale)return imgsensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((224, 224))
if board_cube == 1:sensor.set_vflip(True)sensor.set_hmirror(True)lcd.init(type=2)lcd.rotation(2)
else:lcd.init()fm.register(16, fm.fpioa.GPIOHS0)
key = GPIO(GPIO.GPIOHS0, GPIO.PULL_UP)try:del model
except Exception:pass
try:del classifier
except Exception:passgc.collect()
utils.gc_heap_size(0x40000)
kpu.memtest()  #由于使用的是完整固件,加载smodel会 memory not enough,所以利用utils从gc分配些内存给sys.
model = kpu.load(0x300000)
classifier = kpu.classifier(model, class_num, sample_num)
cap_num = 0
train_status = 0
last_cap_time = 0
last_btn_status = 1
while 1:img = sensor.snapshot()if board_cube:img = img.rotation_corr(z_rotation=90)img.pix_to_ai()# capture imgif train_status == 0: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 = 0last_cap_time = time.ticks_ms()if cap_num < class_num:index = classifier.add_class_img(img)cap_num += 1print("add class img:", index)elif cap_num < class_num + sample_num:index = classifier.add_sample_img(img)cap_num += 1print("add sample img:", index)else:img = draw_string(img, 2, 200, "release boot key please", color=lcd.WHITE,scale=1, bg=lcd.RED)else:time.sleep_ms(30)if key.value() == 1 and (last_btn_status == 0):last_btn_status = 1if cap_num < class_num:img = draw_string(img, 0, 200, "press boot key to cap "+class_names[cap_num], color=lcd.WHITE,scale=1, bg=lcd.RED)elif cap_num < class_num + sample_num:img = draw_string(img, 0, 200, "boot key to cap sample{}".format(cap_num-class_num), color=lcd.WHITE,scale=1, bg=lcd.RED)# train and predictif train_status == 0:if cap_num >= class_num + sample_num:print("start train")img = draw_string(img, 30, 100, "training...", color=lcd.WHITE,scale=2, bg=lcd.RED)lcd.display(img)classifier.train()print("train end")train_status = 1else:res_index = -1try:res_index, min_dist = classifier.predict(img)print("{:.2f}".format(min_dist))except Exception as e:print("predict err:", e)if res_index >= 0 and min_dist < THRESHOLD :print("predict result:", class_names[res_index])img = draw_string(img, 2, 2, class_names[res_index], color=lcd.WHITE,scale=2, bg=lcd.RED)else:print("unknown, maybe:", class_names[res_index])img = draw_string(img, 2, 2, 'maybe {}'.format(class_names[res_index]), color=lcd.WHITE,scale=2, bg=lcd.RED)lcd.display(img)classifier.save("3_classes.classifier") #保存训练集到flash里
#classifier.save("3_classes.classifier")放置到 lcd.display(img)下面以保存特征值。
# You can save trained data to file system by:
#classifier.save("3_classes.classifier")# Then load :
# model = kpu.load(0x300000)
# classifier = kpu.classifier.load(model, "3_class.classifier")

② 加载脚本 self_learning_classifier_load.py

运行加载脚本 不需要再次 按BOOT按键进行拍照学习,

此脚本直接提取 示例脚本 保存到 flash里面的3_classes.classifier数据集,进行目标分类。

下面是加载脚本代码
修改class_name以匹配检测物体(训练模型时,使用的是class来命名)
class_names = ['people', 'xiaoai', 'tf']

import KPU as kpu
import sensor
import lcd
import gc############### config #################
saved_path = "3_classes.classifier"
#如果你使用sd卡:saved_path = "/sd/3_classes.classifier"
THRESHOLD = 11
class_names = ['class1', 'class2', 'class3']
########################################def draw_string(img, x, y, text, color, scale, bg=None ):if bg:img.draw_rectangle(x-2,y-2, len(text)*8*scale+4 , 16*scale, fill=True, color=bg)img = img.draw_string(x, y, text, color=color,scale=scale)return imglcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_windowing((224, 224))try:del model
except Exception:pass
try:del classifier
except Exception:pass
gc.collect()
model = kpu.load(0x300000)
classifier, class_num, sample_num = kpu.classifier.load(model, saved_path)while 1:img = sensor.snapshot()res_index = -1try:res_index, min_dist = classifier.predict(img)print("{:.2f}".format(min_dist))except Exception as e:print("predict err:", e)if res_index >= 0 and min_dist < THRESHOLD :print("predict result:", class_names[res_index])img = draw_string(img, 2, 2, class_names[res_index], color=lcd.WHITE,scale=2, bg=lcd.RED)else:print("unknown, maybe:", class_names[res_index])img = draw_string(img, 2, 2, 'maybe {}'.format(class_names[res_index]), color=lcd.WHITE,scale=2, bg=lcd.RED)lcd.display(img)

四、效果

五、拓展

示例脚本只捕捉了3个物体,我们可以修改class_num等来提高物体数量

class_num = 5 #5个物体
sample_num = 25 #25张训练集
class_names = ['class1', 'class2', 'class3','class4','class5']#物体标签 

在加载脚本处也修改

class_names = ['people', 'xiaoai', 'tf', 'box','mouse']

[K210]Maixpy self learning classifier 自学习分类器相关推荐

  1. SDN实验(四)——Learning Switch自学习交换机

    SDN实验(四)--Learning Switch自学习交换机 一.自学习交换机原理 (一)普通交换机实现 (二)SDN交换机实现 二.自学习交换机代码实现 (一)代码 (二)代码讲解 (三)实验 三 ...

  2. TRAINING A CLASSIFIER训练分类器(pytorch官网60分钟闪电战第四节)

    Training an image classifier训练图像分类器 本节没有写在GPU和多个GPU上训练的代码,主要写了训练图像分类器,分为5个步骤 文章目录 一.Loading and norm ...

  3. OpenCV级联分类器Cascade Classifier

    OpenCV级联分类器Cascade Classifier 级联分类器Cascade Classifier 目标 理论 OpenCV中的Haar级联检测 结果 级联分类器Cascade Classif ...

  4. k210自主学习目标分类

    https://cn.maixpy.sipeed.com/dev/zh/course/ai/basic/maixpy_hardware_ai_basic.html MaixPy AI 硬件加速基本知识 ...

  5. 【github】机器学习(Machine Learning)深度学习(Deep Learning)资料

    转自:https://github.com/ty4z2008/Qix/blob/master/dl.md# <Brief History of Machine Learning> 介绍:这 ...

  6. 机器学习(Machine Learning)深度学习(Deep Learning)资料汇总

    本文来源:https://github.com/ty4z2008/Qix/blob/master/dl.md 机器学习(Machine Learning)&深度学习(Deep Learning ...

  7. 机器学习----(Machine Learning)深度学习(Deep Learning)资料(Chapter 1)

    文章转至:作者:yf210yf  感谢您提供的资源 资料汇总的很多,转载一下也方便自己以后慢慢学习 注:机器学习资料篇目一共500条,篇目二开始更新 希望转载的朋友,你可以不用联系我.但是一定要保留原 ...

  8. 机器学习(Machine Learning)深度学习(Deep Learning)资料集合

    机器学习(Machine Learning)&深度学习(Deep Learning)资料 原文链接:https://github.com/ty4z2008/Qix/blob/master/dl ...

  9. 机器学习(Machine Learning)深度学习(Deep Learning)资料(Chapter 1

    <Brief History of Machine Learning> 介绍:这是一篇介绍机器学习历史的文章,介绍很全面,从感知机.神经网络.决策树.SVM.Adaboost到随机森林.D ...

最新文章

  1. 使用IB_DESIGNABLE与IBInspectable特性实现可在视图编辑器的功能栏中设置
  2. 这四种情况下,才是考虑分库分表的时候!
  3. mysql数据中文乱码_win10 系统解决mysql中文乱码问题
  4. 查询字符串某个字符的个数
  5. Centos7 error: Failed to initialize NSS library
  6. linux的yum命令无法使用在哪里下载_Linux 知识分享:为Linux的cp和mv命令添加进度条...
  7. vue axios 简单封装以及思考
  8. (Windows7)Visual Studio 2017编译运行出现脚本错误的解决方法
  9. JavaScript可变参数个数
  10. Ross《概率论基础教程》—Note 1
  11. java 判断文件编码格式(支持zip)
  12. docker安装gamit_gamit的安装步骤
  13. 一文讲透高速缓存原理
  14. 先秦经典智慧名言故事丛书(全16册) 内容简介
  15. 为什么我会性格懦弱?如何改变懦弱的性格?
  16. 车架号VIN码精准查询车辆信息
  17. C#练习之判断字符串是否为回文
  18. calendar java 线程安全_Calendar(线程不安全)
  19. 安卓rom包解包linux,Android rom解包打包工具
  20. 如何快速学习一门编程语言

热门文章

  1. 运筹学基础,这个可以懂(上)
  2. 初步掌握MapReduce的架构及原理
  3. Python实现网站自动登录---傻瓜教程
  4. 计算机音乐烟火人间,烟火人间在线试听_陆虎_高音质歌曲_九酷音乐
  5. 15类图神经网络的应用场景总结
  6. matlab 水波模拟 代码,matlab - 在Matlab中模拟一艘在水波中航行的船 - SO中文参考 - www.soinside.com...
  7. 【51单片机】HX711智能电子秤语音播报蓝牙传输设计
  8. java 中 IO 流分为几种?
  9. Intel Xeon Platinum 8269CY(Cascade Lake)处理器性能评测
  10. 如何快速查询mysql_mysql如何快速查询