21电赛送药小车k210识别数字(测试有效)

21电赛送药小车k210识别数字(测试有效)

##前言

目前,k210在电赛选手心中的地位越来越高,毕竟性能强,并且价格相比较于openmv和树莓派会更便宜。其实刚开始是打算用openmv进行的,为此还买了最新版的openmv(openMv4 H7 Plus),因为能力有限,我也是一个小白

一开始,使用了模板匹配,但是模板匹配很严格,远了一点,角度变了一点就会识别不出来,如果录入太多的模板,就会导致识别时间变长。

后来,使用了特征点检测,这个效果比模板匹配好一点,但是,经常3和8不分,1和7不分,并且模板匹配和特征点检测还有一个很致命的缺点,就是非常容易受背景的影响,所以最后也被我pass掉了

接着,我又用openmv跑深度学习,结果出来的效果也非常不好,来来回回取了好几次样,后面有一次,一个数字为了1000张数据,把每一个模型都跑了一边,并且还构建了好几次数据集,花费了大量的时间,但是最后也没能够达到想要的结果。

因为能力有限,没能够用openmv完成这个任务,最后我选择使用k210进行识别,中间也遇到了很多的问题,所幸最后效果还可以。

希望通过分享我在备战电赛过程中踩过的坑,能够帮助大家少走弯路

数据集的采集

我是通过k210直接采集数据,会省去很多对照片进行处理的步骤,在采集照片时一定要插SD卡,因为k210的flash有限,无法存储照片,将数据存储在 SD卡中,然后通过读卡器读出就行了。

这里我尝试了两种采集的方法,一种是通过串口,定时发送,k210这种适合用于连续拍摄,可以在短时间内收集到大量的数据集,另一种方法是通过按键进行拍照。注意:不要在k210的主函数中直接加延迟,进行定时拍照,这样会导致k210拍摄的画面不能够及时传回,画面会非常卡

(1)保存照片到SD卡的方法

在k210使用一个函数就可以完成这个任务

sensor.snapshot().save("/sd/" + str(num) + "1" + ".jpg")

在保存数据时,每次复位k210,都要将".jpg"前面的“1”换成别的数字,防止因为名字重复,将原先的数据覆盖掉

(2)使用串口进行定时拍照

这里我们接收到b’\x16’,就将一张照片保存到SD卡中。

串口的配置如下

import sensor, time, image                                  # 导入感光元件模块 sensor 跟踪运行时间模块 time 机器视觉模块 image
import utime                                                # 导入延时模块 utime
from fpioa_manager import fm                                # 从 fpioa_manager 模块中导入 引脚注册模块 fm
from Maix import GPIO                                       # 从 Maix 模块中导入 模块 GPIO
import lcd                                                  # 导入 LCD 模块
from machine import UART

# 感光元件设置
sensor.reset()                                              # 重置并初始化感光元件 默认设置为 摄像头频率 24M 不开启双缓冲模式
#sensor.reset(freq=24000000, dual_buff=True)                # 设置摄像头频率 24M 开启双缓冲模式 会提高帧率 但内存占用增加

sensor.set_pixformat(sensor.RGB565)                         # 设置图像格式为 RGB565 (彩色) 除此之外 还可设置格式为 GRAYSCALE 或者 YUV422
sensor.set_framesize(sensor.QVGA)                           # 设置图像大小为 QVGA (320 x 240) 像素个数 76800 K210最大支持格式为 VGA

sensor.set_auto_exposure(0)                                 # 关闭自动曝光
#sensor.set_auto_exposure(0, exposure=120000)               # 设置手动曝光 曝光时间 120000 us

#sensor.set_auto_gain(0)                                    # 关闭画面增益
sensor.set_auto_gain(0, gain_db = 16)                       # 设置画面增益 16 dB 影响实时画面亮度

sensor.set_auto_whitebal(0)                                 # 关闭RGB自动增益(白平衡)
#sensor.set_auto_whitebal(0, rgb_gain_db = (0,0,0))         # 设置RGB增益 0 0 0 dB 影响画面色彩呈现效果 在 K210 上无法调节增益 初步判定是感光元件 ov2640 无法支持

#sensor.set_contrast(0)                                     # 设置对比度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释
#sensor.set_brightness(0)                                   # 设置亮度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释
#sensor.set_saturation(0)                                   # 设置饱和度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释

#sensor.set_vflip(1)                                         # 打开垂直翻转 如果是 01Studio 的 K210 不开启会导致画面方向与运动方向相反
#sensor.set_hmirror(1)                                       # 打开水平镜像 如果是 01Studio 的 K210 不开启会导致画面方向与运动方向相反

sensor.set_windowing((224,224))                             # 设置图像大小为 224 224

sensor.skip_frames(time = 2000)
lcd.init(freq=15000000)

#__________________________________________________________________
from board import board_info
fm.register(24, fm.fpioa.UART1_TX, force=True)
fm.register(25, fm.fpioa.UART1_RX, force=True)
uart_A = UART(UART.UART1, 115200, 8, 0, 0, timeout=1000, read_buf_len=4096)
#__________________________________________________________________
#sensor.snapshot().save("/sd/img/000"+str(key.img_cnt)+".jpg")
num = 0

while(1):
    img = sensor.snapshot()
    lcd.display(img)
    n = uart_A.read()
    if(n != None):
        print(n)
    if(n == b'\x16'):
        img.save("/sd/7/" + str(num) + "1" + ".jpg")
        print(num)
        num = num + 1


然后我们通过野火的串口助手,实现定时发送,进行拍照

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0gyD06vg-1692262154335)(21电赛送药小车k210识别数字(测试有效).

在这里插入图片描述

这里的波特率要与k210配置为一样的,通过改变发送周期,然后来改变拍照的周期。

(3)使用按键进行拍照

这个方法是我觉得最好的,可以等图像稳定了在进行取样。

这个代码我也是借鉴了一位大佬的文章,非常推荐大家去看看原文

大佬的文章


#__________________________________________________________________
# 导入模块
import sensor, time, image                                  # 导入感光元件模块 sensor 跟踪运行时间模块 time 机器视觉模块 image
import utime                                                # 导入延时模块 utime
from fpioa_manager import fm                                # 从 fpioa_manager 模块中导入 引脚注册模块 fm
from Maix import GPIO                                       # 从 Maix 模块中导入 模块 GPIO
import lcd                                                  # 导入 LCD 模块

#__________________________________________________________________
# 感光元件设置
sensor.reset()                                              # 重置并初始化感光元件 默认设置为 摄像头频率 24M 不开启双缓冲模式
#sensor.reset(freq=24000000, dual_buff=True)                # 设置摄像头频率 24M 开启双缓冲模式 会提高帧率 但内存占用增加

sensor.set_pixformat(sensor.RGB565)                         # 设置图像格式为 RGB565 (彩色) 除此之外 还可设置格式为 GRAYSCALE 或者 YUV422
sensor.set_framesize(sensor.QVGA)                           # 设置图像大小为 QVGA (320 x 240) 像素个数 76800 K210最大支持格式为 VGA

sensor.set_auto_exposure(0)                                 # 关闭自动曝光
#sensor.set_auto_exposure(0, exposure=120000)               # 设置手动曝光 曝光时间 120000 us

#sensor.set_auto_gain(0)                                    # 关闭画面增益
sensor.set_auto_gain(0, gain_db = 16)                       # 设置画面增益 16 dB 影响实时画面亮度

sensor.set_auto_whitebal(0)                                 # 关闭RGB自动增益(白平衡)
#sensor.set_auto_whitebal(0, rgb_gain_db = (0,0,0))         # 设置RGB增益 0 0 0 dB 影响画面色彩呈现效果 在 K210 上无法调节增益 初步判定是感光元件 ov2640 无法支持

#sensor.set_contrast(0)                                     # 设置对比度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释
#sensor.set_brightness(0)                                   # 设置亮度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释
#sensor.set_saturation(0)                                   # 设置饱和度 0 这个参数无法读取 且调这个参数对画面似乎不会产生影响 暂时注释

#sensor.set_vflip(1)                                         # 打开垂直翻转 如果是 01Studio 的 K210 不开启会导致画面方向与运动方向相反
#sensor.set_hmirror(1)                                       # 打开水平镜像 如果是 01Studio 的 K210 不开启会导致画面方向与运动方向相反

sensor.set_windowing((224,224))                             # 设置图像大小为 224 224

sensor.skip_frames(time = 2000)                             # 延时跳过2s 等待感光元件稳定

#__________________________________________________________________
# 创建时钟对象
clock = time.clock()                                        # 创建时钟对象 clock

#__________________________________________________________________
# LED的使用
# 注册 LED 引脚
fm.register(14, fm.fpioa.GPIO2, force = True)               # 配置 14 脚为 LED_R 强制注册
fm.register(13, fm.fpioa.GPIO1, force = True)               # 配置 13 脚为 LED_G 强制注册
fm.register(12, fm.fpioa.GPIO0, force = True)               # 配置 12 脚为 LED_B 强制注册

# 创建 LED 对象
LED_R = GPIO(GPIO.GPIO2, GPIO.OUT)                          # 创建 LED_R 对象
LED_G = GPIO(GPIO.GPIO1, GPIO.OUT)                          # 创建 LED_G 对象
LED_B = GPIO(GPIO.GPIO0, GPIO.OUT)                          # 创建 LED_B 对象

# LED控制函数
def LED_Control(led_flag):                                  # LED控制函数 根据传入 led_flag 点亮对应的灯 需要注意的是 0为点亮 1为熄灭
    if led_flag == 0:                                       # 传入参数为 0 所有灯打开
        LED_R.value(0)
        LED_G.value(0)
        LED_B.value(0)

    elif led_flag == 1:                                     # 传入参数为 1 所有灯关闭
        LED_R.value(1)
        LED_G.value(1)
        LED_B.value(1)

    elif led_flag == 2:                                     # 传入参数为 2 红灯常亮
        LED_R.value(0)
        LED_G.value(1)
        LED_B.value(1)

    elif led_flag == 3:                                     # 传入参数为 3 绿灯常亮
        LED_R.value(1)
        LED_G.value(0)
        LED_B.value(1)

    elif led_flag == 4:                                     # 传入参数为 4 蓝灯常亮
        LED_R.value(1)
        LED_G.value(1)
        LED_B.value(0)

    else:                                                   # 其他情况 紫灯
        LED_R.value(0)
        LED_G.value(1)
        LED_B.value(0)

#__________________________________________________________________
# 按键的使用
# 定义按键控制类
class Key_Control():                                        # 定义按键控制类
    cnt     = 0                                             # 按键计数值
    cs      = 0                                             # 按键模式选择标志位
    csmax   = 0                                             # 按键模式上限
    csflag  = 0                                             # 按键模式切换标志位
    cinput  = 0                                             # 按键输入值保存位
    control = 0                                             # 按键确认及发送控制标志位
    img_cnt = 0                                             # 照片计数值

# 实例化按键类
key = Key_Control()                                         # 实例化按键控制类 Key_Control() 为 key
key.csmax = 3                                               # 按键模式上限为 3 即最多有 4 个模式 (0, 1, 2, 3)

# 注册按键引脚
fm.register(16, fm.fpioa.GPIOHS0, force = True)             # 配置 16 脚为 KEY0 使用高速 GPIO 口 强制注册

# 创建按键对象
KEY0 = GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)            # 创建按键对象 KEY0

# 中断回调函数 KEY0 控制按键模式选择
def Key0_Switch(KEY0):
    utime.sleep_ms(10)                                      # 延时 10ms 消除按键抖动
    if KEY0.value() == 0:                                   # 确认 按键0 按下
        key.csflag = 1                                      # 标记按键模式切换
        if key.cs < key.csmax:                              # 若当前按键模式值小于按键模式选择上限值
            key.cs = key.cs + 1                             # 控制按键模式选择 自增
        else:                                               # 若达到上限 则重新从 0 开始
            key.cs = 0
        Get_Image(key)                                      # 触发中断的时候拍摄一张照片

# 开启中断 下降沿触发
KEY0.irq(Key0_Switch, GPIO.IRQ_FALLING)                     # 开启 按键0 外部中断 下降沿触发

#__________________________________________________________________
# 获取照片函数
def Get_Image(key):
    # 拍摄一张照片 保存到 SD卡 的 img 目录下 名字为 000 + key.img_cnt.jpg 如 0001.jpg
    if key.img_cnt < 10:
        sensor.snapshot().save("/sd/img/000"+str(key.img_cnt)+".jpg")
    elif key.img_cnt < 100:
        sensor.snapshot().save("/sd/img/00"+str(key.img_cnt)+".jpg")
    elif key.img_cnt < 1000:
        sensor.snapshot().save("/sd/img/0"+str(key.img_cnt)+".jpg")
    elif key.img_cnt < 10000:
        sensor.snapshot().save("/sd/img/"+str(key.img_cnt)+".jpg")

    key.img_cnt = key.img_cnt + 1                           # 计数值自增

#__________________________________________________________________
# LCD
# LCD 初始化
lcd.init()                                                  # lcd初始化

# LCD 打印照片张数
def LCD_Show():
    lcd.draw_string(0, 0,  "img_cnt: "+str(key.img_cnt), lcd.BLUE, lcd.WHITE)
    lcd.draw_string(0, 15, "Gain   : "+str(sensor.get_gain_db()), lcd.BLUE, lcd.WHITE)
    lcd.draw_string(0, 30, "RGBGain: "+str(sensor.get_rgb_gain_db()), lcd.BLUE, lcd.WHITE)

#__________________________________________________________________
# 照片起始序号设置
key.img_cnt = 0

#__________________________________________________________________
# 主函数模式选择
while(True):

    clock.tick()                                            # 跟踪运行时间
    img=sensor.snapshot()                                   # 摄像头拍摄一张图片
    lcd.display(img)                                        # LCD 显示图像
    LCD_Show()                                              # LCD 显示照片张数
    LED_Control(key.cs)                                     # 按键控制 LED 表示按键有成功按下
    print(key.img_cnt)

#__________________________________________________________________


模型的训练

模型的训练操作就比较简单,主要是比较繁琐。

大家可以到网上去寻找一些MaixHub的使用教程,都非常简单,这里就不跟大家废话了。

直接给大家推荐一下大佬的文章

http://t.csdn.cn/VjXPz

就主要说一下如何提高训练模型的准确性,首先训练集对最后的效果影响是非常大的。我们可能会以为多角度,多方位的数据集会好一点,但经过我的尝试,一味的追求多元化是达不到很好的效果的。反而少量角度进行大量拍摄反而能达到比较好的效果。还有一点,数据集的采样环境,尽量与实际识别环境相同。

就以21年的为例,有几个注意点:

###提高准确率的技巧

(1)因为基本是两个数字一起识别的,所以我们在构建数据集的时候,可以大部分是一张照片里面包含两个个数字。

在这里插入图片描述

(2)还有道路上3~8是随机摆放的,所以我们就要把每一种情况的数据都采集一些,比如3和8,4和7之类的,还有就是3在左边,8在右边,与8在左边,3在右边,不要小看这一小小的改变,影响是非常大的。

训练的模型和调试的步骤

这只是我调试过程中找到的一个我感觉效果不错的流程,不完全正确,毕竟我不是专业,但是亲测效果还不错,大家可以试一试。

(1)先对每张照片进行数字单独采样,每个数字正面和小角度偏转大概50张左右。

(2)两个数字一起采样,每个数字也是正面和小角度偏转大概100张左右,以上两个步骤采样的照片相似的可以多一点,因为我们一般就在这个范围进行采样。记得要按照上面的技巧进行采样

8是随机摆放的,所以我们就要把每一种情况的数据都采集一些,比如3和8,4和7之类的,还有就是3在左边,8在右边,与8在左边,3在右边,不要小看这一小小的改变,影响是非常大的。**

  • 5
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: K210数字识别模型是一种基于K210芯片和深度学习算法的模型。K210芯片是一款具有高性能、低功耗特点的人工智能处理芯片,具备硬件加速能力,能够实现高效的神经网络计算。该模型主要用于对数字图像进行自动识别和分类。 K210数字识别模型采用了卷积神经网络(Convolutional Neural Network,CNN)算法。CNN是一种广泛应用于计算机视觉领域的深度学习模型,能够有效地提取图像特征并进行分类识别。在K210芯片上实施CNN模型,可以充分利用其硬件加速能力,提高计算效率和识别准确率。 该模型在训练阶段,通过大量的数字图像样本进行神经网络模型的训练,使其能够学习数字图像的特征和分类规律。在测试阶段,将输入的数字图像通过该模型进行前向传播,即通过一系列的卷积、池化和全连接操作,得到最终的分类结果。 K210数字识别模型的优势在于其高效性和准确性。由于K210芯片的硬件加速能力,该模型在进行图像处理和分类时能够实现快速的计算速度,可以高效地对大规模的数字图像进行识别。同时,该模型经过训练和测试的准确率较高,能够对不同类型的数字图像进行精确的分类,并能够应对一定程度的图像变形和噪声干扰。 总而言之,K210数字识别模型是一种利用K210芯片和深度学习算法实现的数字图像识别模型。其具备高效性和准确性的特点,可以广泛应用于数字图像的识别和分类任务中。 ### 回答2: K210数字识别模型是一种基于K210芯片开发的模型,用于实现对数字识别任务。K210芯片是一种嵌入式人工智能芯片,具有低功耗、高性能的特点,适合用于物联网、智能终端设备等领域。数字识别模型可以应用于手写数字识别、车牌号码识别、货币识别等多个领域。 K210数字识别模型的实现过程包括数据集的准备、模型的搭建和训练,以及模型的评估和优化。首先,需要准备一个包含大量数字样本的数据集,可以通过手动标注、图像采集等方式获取。然后,利用K210芯片的开发环境,搭建起数字识别模型的网络结构,例如使用卷积神经网络(CNN)等模型。接下来,将数据集分为训练集和测试集,利用训练集对模型进行训练,通过反向传播算法不断调整模型参数,使其达到较好的识别效果。在训练过程中,可以设置合适的学习率、迭代次数等超参数来提高模型的性能。最后,使用测试集对模型进行评估,计算准确率、召回率等指标来衡量模型的优劣,并根据评估结果进行模型的优化和改进。 K210数字识别模型的应用广泛,可以用于自动化识别系统、智能家居、智能安防等各个领域。例如,在自动化识别系统中,可以用于快递包裹的自动分拣,通过拍摄包裹上的数字,快速准确地识别出包裹的目标地址。在智能安防领域,可以用于车牌号码的识别,实现车辆的自动进出管理。此外,还可以应用于智能家居领域的数字手势识别,通过识别手势指令,实现对家居设备的智能控制。 总之,K210数字识别模型是一种利用K210芯片实现的模型,可用于数字识别任务,具有广泛的应用前景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值