2021电赛F题数字识别和巡线部分

2023-05-16

文章之前12月发了一次,但是我后来申请的免毕设后,用到了一些文字,所以删了这篇文章,但是还是查重了,于是我把一些程序讲解先删了,等毕设结束后再编辑加上。

这次电赛我没有准备多少东西,只提前准备了图像识别和坐标计算一类的。在20年的省赛帮过雪地调过k210后,自己后来为了比赛,也买了一个。参加了省物联网和交通科技比赛。


由于这边学校对竞赛支持力度不大,经费不多,所以我就用了一块k210.用它作识别和巡线其实是完全够用的。只需要写个判断分开就好。

识别这块我起初自己配的aconda和pycharm环境,不过出现各种问题,没耐下心去做(这学期课程依旧很多,而且还有别的事)。直接用了mxyolo这款软件,一键配置环境库,再加上英伟达cuda加速就可以了。

我用了总共600张图片,花了20分钟大概(我的老笔记本gtx1050,没有独显直连所以也没有出过视频了。) 对象的1650大概在10分钟出头。标记是门体力活,好在有了不错的识别效果,图片样本拍摄是在不同光线和距离情况下,最终模型识别成功率大概在80%左右,速度很快。只是,7容易识别成1,5有时候会识别成2,这是在距离不定的情况下,我想是训练数据集不够。迭代在30,loss挺低了。

在摄像头悬空情况下,正好可以识别2-3个数字。

软件图后续想起来再补吧,我突然想写文章时候发现当时并没有截图。

再说一说软件部分吧,k210我是在Maixpy下进行编写的,调用外设库非常方便,只是没有花括号的缩进,我看着很难受。

初始化程序打开了各个外设以及定义了灰度值,灰度值需要在菜单栏里的——工具——机器视觉——阈值编辑器,选择帧缓冲图像,拖动滚动条,把红线与地面的背景分隔开。红线为白,其它为黑。(麻了,我又没存图,当时只留意存了十字线和巡线的。)

import sensor,image,lcd,time
import KPU as kpu
from Maix import FPIOA, GPIO
from fpioa_manager import fm
from board import board_info
from machine import UART
from Maix import GPIO

fm.register(17, fm.fpioa.GPIO0, force=True)
s_flag = GPIO(GPIO.GPIO0, GPIO.OUT)

flag=1

GRAYSCALE_THRESHOLD = [(87, 255)]    #划分的灰度值
THRESHOLD =(10, 34, -41, 74, -109, 127)   #摄像头垂直于地面

lcd.init(freq=15000000)
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
#sensor.set_hmirror(0)   #镜像
#sensor.set_vflip(1)     #翻转
lcd.rotation(2)     #旋转方向 参数是0~3, 分别代表顺时针旋转 0度 90度 180度 270度
sensor.set_windowing((224, 224))
#sensor.set_brightness(2)
sensor.run(1)
clock = time.clock()

fm.register(23,fm.fpioa.UART2_TX)
uart_A = UART(UART.UART2, 115200, 8, None, 1, timeout=1000, read_buf_len=4096)

task = kpu.load("/sd/tt.kmodel")
f=open("anchors.txt","r")
anchor_txt=f.read()
L=[]
for i in anchor_txt.split(","):
    L.append(float(i))
anchor=tuple(L)
f.close()
a = kpu.init_yolo2(task, 0.6, 0.3, 5, anchor)

f=open("lable.txt","r")
labels_txt=f.read()
labels = labels_txt.split(",")
f.close()


死循环中我是通过标志位来切换两种模式的。首先上电先进入数字识别,第一次完成后进入巡线程序。后续切换是通过另一个主控发送数据改变的。

主控那边我简单说下吧,是通过闭环加入编码器计里程和十字线辅助判断每个路口,自加是第几个路口,停下来发信号给k210,在开始数字判断。

下面程序是老版本的,少写一些通信,数字在屏幕的左右正负偏差坐标即是数字在病房路口的位置,通过这个信息去PWM差速转向。

使用的PD进行转向控制,能精确锁住中线行驶。主控我认为用什么都可以,stc12啊,stc8都可以。之前自己做亚克力小车,加升压,在智能车赛道上一圈开环也能跑个16-18秒(没有加三岔路和圆环)。

这次比赛我用的是GD32的芯片,因为便宜,他们家封装的库还是挺好用的。

   

 

 这题我选择后,第一天深夜我才确定用摄像头方案,以前没有试过巡线,凌晨3点从openmv那里速成,代码搬过来了。后续我想学学opencv。

发现这题坑真多,量很大,光靠我一个人肯定做不完,所以需要点取巧的方法。

开环直线行驶很稳定,但是到十字路口会被干扰,于是我加了判断,并且把左右两边的白色区域给忽略了,还是当作一条直线。(在主控上根据我经过的十字路口和数字进行综合判断的)

def c_line():
    s_flag.value(1) #识别到数字后17口高电平s
    img = sensor.snapshot().binary([THRESHOLD])
    lcd.display(img)

    roi0=(80, 0,30, 30)     #给识别中线的位置标上兴趣框,并画下来,验证。
    most_pixels=0
    img.draw_rectangle(roi0, color =170)
    blob0 = img.find_blobs(GRAYSCALE_THRESHOLD, roi=roi0,pixels_threshold=100, area_threshold=100, merge=True)
    if blob0:
        for n in range(len(blob0)):
        #目标区域找到的颜色块(线段块)可能不止一个,找到最大的一个,作为本区域内的目标直线
           if blob0[n].pixels() > most_pixels:
               most_pixels = blob0[n].pixels()
               #merged_blobs[i][4]是这个颜色块的像素总数,如果此颜色块像素总数大于
               largest_blob = n
           R = 1

    else:
        R = 0

    roi1=(80, 200,30, 30)
    img.draw_rectangle(roi1, color =170)
    blob1 = img.find_blobs(GRAYSCALE_THRESHOLD, roi=roi1,pixels_threshold=100, area_threshold=100, merge=True)
    if blob1:
        for n in range(len(blob1)):
           if blob1[n].pixels() > most_pixels:
               most_pixels = blob1[n].pixels()
               largest_blob = n
           L = 1

    else:
        L = 0
    uart_A.write('L')
    uart_A.write(str(L))
    uart_A.write('Z')

    uart_A.write('R')
    uart_A.write(str(R))
    uart_A.write('X')

    line=img.get_regression([(20, 250)],roi=(0,0,210,210),x_srtide=2,y_srtide=1,robust=False)  #灰度 白黑
    if(line):
        rho_err = abs(line.rho())-img.width()/2   #piancha
        #print(int(rho_err))
        uart_A.write('P')
        uart_A.write(str(int(rho_err)))
        uart_A.write('S')
        if line.theta()>90:
            theta_err = line.theta()-180
        else:
            theta_err = line.theta()
        img.draw_line(line.line(), color = 127)

        print('R',R ,'L',L)

        #print(rho_err,line.magnitude(),theta_err)

下面部分是识别数字的,比较简单,都是框架。因为比赛自己做自己用的,串口没有用到多严格的格式,只加了头尾,确保传的数正确就好。主控那边我加了语音播报病房号,也算个额外加分点,这个屡试不爽~ 

def c_num():
    global flag
    img = sensor.snapshot()
    code = kpu.run_yolo2(task, img)
    print(anchor)
    a = lcd.display(img)
    if code:
        for i in code:
            a=img.draw_rectangle(i.rect(),(0,255,0),2)
            a = lcd.display(img)
            for i in code:
                lcd.draw_string(i.x()+45, i.y()-5, labels[i.classid()]+" "+'%.2f'%i.value(), lcd.WHITE,lcd.GREEN)
                #print(labels[i.classid()])
                #print('x',i.x(),y,'i.y()')
                if(labels[i.classid()]=='1'):
                    #print('1')
                    uart_A.write('N')
                    uart_A.write('1')
                    uart_A.write('M')

                if(labels[i.classid()]==' 2'):
                    uart_A.write('N')
                    uart_A.write('2')
                    uart_A.write('M')
                if(labels[i.classid()]==' 3'):
                    uart_A.write('N')
                    uart_A.write('3')
                    uart_A.write('M')
                if(labels[i.classid()]==' 4'):
                    uart_A.write('N')
                    uart_A.write('4')
                    uart_A.write('M')
                if(labels[i.classid()]==' 5'):
                    uart_A.write('N')
                    uart_A.write('5')
                    uart_A.write('M')
                if(labels[i.classid()]==' 6'):
                    uart_A.write('N')
                    uart_A.write('6')
                    uart_A.write('M')
                if(labels[i.classid()]==' 7'):
                    uart_A.write('N')
                    uart_A.write('7')
                    uart_A.write('M')
                if(labels[i.classid()]==' 8'):
                    uart_A.write('N')
                    uart_A.write('8')
                    uart_A.write('M')


        flag=0
        s_flag.value(0)
    else:
        a = lcd.display(img)
        #uart_A.write('N')
        #uart_A.write('0')
        #uart_A.write('M')

Python我并没有好好学过,几乎没写过几次,都是临时抱佛脚,代码写的很烂。 这次没有什么详细讲解,代码直接甩出去,(不负责的我,这次写完就不想补充完善了)留给大家自己慢慢研究了。我感觉除了那个灰度图像阈值需要自己调整外,其他没有什么太大问题。

额,这次比完赛并没有完赛资料,就没有参加立创开源,少拿一份奖金,不过问题不大,我懒。

立创的奖金比学校的还要高,学校又要降奖金,因为今年拿奖的、参赛的人多了,我笑了……这学校各种恶心人的事,摆烂等我毕业答辩完再说。真不如我在一个好专科待遇好。

白嫖个便携式示波器挺好的。

继19年电赛在专科拿过一次国一后,没想到在本科这边又拿了一次。唯一一次遗憾的就是智能车了,但那个是外在因素,等完全毕业之后再谈。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2021电赛F题数字识别和巡线部分 的相关文章

  • 2021 CondaHTTPError: HTTP 000 CONNECTION FAILED for url 的问题终极解决方案

    一 首先执行命令 xff0c 查看自己的镜像源 conda config show channels 二 可以首先删除已经存在的镜像源 xff08 注 xff1a 上述三个镜像源无需删除 xff01 xff01 xff01 xff09 xf
  • 恒温箱课程设计(2021.4.12)

    第一步 方案选择 淘宝闲鱼csdn 主要难点在于 xff1a 小控大是难点 xff0c 对执行器和驱动的选择 最终 电磁和固态继电器都不行 xff0c 要可控相位的继电器 xff0c 太贵了 只能固态了 xff0c if控制 xff0c 效
  • Redis面试题(2021最新)

    文章目录 概述什么是RedisRedis有哪些优缺点为什么要用 Redis 为什么要用缓存 为什么要用 Redis 而不用 map guava 做缓存 Redis为什么这么快 数据类型Redis有哪些数据类型Redis的应用场景 持久化什么
  • MySQL数据库面试题(2021最新版)

    文章目录 1 数据库基础知识为什么要使用数据库什么是SQL 什么是MySQL 数据库三大范式是什么MySQL有关权限的表都有哪几个MySQL的binlog有有几种录入格式 xff1f 分别有什么区别 xff1f 2 引擎MySQL存储引擎M
  • 北理工-2021年春-《数字逻辑》实验

    北理工 2021年春 数字逻辑 实验 实验二 组合电路设计 实验目的 本实验通过设计一个组合电路实例 xff0c 让学生掌握组合逻辑电路从设计到验证的全过程 通过该实验 xff0c 可以加深学生对组合电路原理和设计的理解 xff0c 同时可
  • 最新C语言编程软件推荐(2021整理)

    一 C语言编程软件推荐 C语言编程软件适于编写系统软件 xff0c 是学习编程的同学们的必备软件 c语言一种应用非常广泛的编程语言 xff0c 不仅仅是在软件开发上 xff0c 而且各类科研都会用到c语言 今天小编给大家汇总下C语言的编程软
  • 2021-前端-VsCode插件

    此乃吾习前端 xff0c VsCode之插件 xff0c 个人所装 xff0c 喜着自拿 xff0c 不足之处还望海涵 xff0c 多加批评 1 Auto Close Tag 自动闭合尾部的标签 2 Atuo Rename Tag 修改 h
  • 2021-09-17

    https d2lzkl7pfhq30w cloudfront net pub archive epel 6 x86 64 以上是epel的新地址
  • 2021-09-14

    eclipse maven run 错误 xff1a Fatal error compiling 无效的标记 release maven compiler plugin 3 8 1 中使用release便签eclipse 使用 Run gt
  • 【2021最新版】JavaOOP面试题总结(99道题含答案解析)

    文章目录 1 什么是B S架构 xff1f 什么是C S架构2 Java都有那些开发平台 xff1f 3 什么是JDK xff1f 什么是JRE 4 Java语言有哪些特点5 面向对象和面向过程的区别6 什么是数据结构 xff1f 7 Ja
  • 2021-01-20

    中文字库液晶模块12864示例程序范例 xff1a 液晶屏型号 xff1a JLX12864G 086 PC 3S 接口 xff1a 串行 中文字库 xff1a 带中文字库IC JLX GB2312 竖置横排 驱动IC UC1701X 与S
  • 2021-02-13

    昨天学习了关于位运算的一些常识 xff0c 自己也跟着视频敲了一些位运算代码如下 xff1a package com raisecom tiap ems basic mgt domain acl import java util Array
  • 位姿图优化小记2021.10.18

    1 场景描述 现在有一个小车在运动 xff0c 并搭载相机或激光雷达进行建图工作 xff0c 由于SLAM的作用 xff0c 在建图的同时小车也可以进行自身的定位 xff0c 因此建立的地图的参考都是相对于自身坐标系的 xff0c 也就是每
  • 2021-03-16

    hullib Rtc 获取时间之后必须获取日期他才会有时间 HAL RTC GetTime amp hrtc amp sTime RTC FORMAT BIN HAL RTC GetDate amp hrtc amp sDate RTC F
  • Daily practice——2021/1/31

    1 函数若无返回值 则它一定无形参 请问这个说法是正确的吗 xff1f 答 xff1a 这个说法不正确 一个函数可以有参数 xff0c 没有返回值 xff1b 可以没有参数 xff0c 有返回值 xff1b 可以没参数 xff0c 没返回值
  • 2021-08-19-leetcode-00001

    二分查找 704 给定一个 n 个元素有序的 xff08 升序 xff09 整型数组 nums 和一个目标值 target xff0c 写一个函数搜索 nums 中的 target xff0c 如果目标值存在返回下标 xff0c 否则返回
  • rosdep update 超时失败2021最新解决方法

    好记性不如烂笔头 xff0c 记录方法 xff0c 方便大家 一 关于 rosdep 安装ros的最后一步是rosdep init和rosdep update xff0c rosdep是解决ros包依赖问题的一个工具 rosdep init
  • 2021-11-11 机械臂路径规划学习进展

    机械臂关节空间和末端空间路径规划 关节空间路径规划简单障碍物情况 xff1a 之后搭建复杂障碍物场景 xff1a 测试发现路径规划的两个步骤 xff1a 采用了关节空间进行路径规划的方案 xff0c 原因主要是在关节空间也就是构型空间中 x
  • 2021-05-14 Redis面试题 redis 部署生产环境

    redis 部署生产环境 redis cluster xff0c 10 台机器 xff0c 5 台机器部署了 redis 主实例 xff0c 另外 5 台机器部署了 redis 的从实例 xff0c 每个主实例挂了一个从实例 xff0c 5
  • Pixi.js 显示文字无法换行

    官方案例 message style wordWrap true wordWrapWidth 100 align center 中文无法换行 设置breakWords属性 sprite style wordWrap true wordWra

随机推荐

  • 串口测试例程

    串口分为RS232和TTL xff0c 所以在测试前请先确认自己的串口类型进行测试 下面以海思的一个RS232串口为例说明一下具体的测试过程 xff0c 串口测试代码参考的为讯为提供的 xff0c 在其基础上做的调整 1 确定接口 xff0
  • C语言中的字符串初始化

    1 C语言没有字符串类型 xff0c 通过字符数组模拟 xff0c C语言字符串 xff0c 以字符 0 数字0 2 数组指定长度后 xff0c 后面没有赋值的元素 xff0c 自动补0 char buf 100 61 39 a 39 39
  • 自动收取蚂蚁森林能量雨

    首先 xff0c 说明一下 这是一个非常迂回且效果不佳的方法 xff0c 小弟不才 xff0c 安卓以及苹果手机上的脚本没啥研究 xff0c PC的按键精灵略懂 xff0c 因此才有一下脚本 觉得有用拿去参考 xff0c 大佬勿喷 我一直都
  • AD中画圆弧形板框的方法

    在实际的板框设计中 xff0c 有时为了生产需要 xff0c 不得不需要将PCB板设计成四角需要倒角的形式 xff0c 经过实际的摸索 xff0c 现在得出一种画圆形板框的小技巧 现在需要将板框设计成3 5mm半径样式 xff08 1 xf
  • AD中板内挖空的方法

    一 先使用禁止布线层将板框确定 使用的快捷键 xff1a D gt S gt D 二 再绘制一个挖空区域 使用的快捷键 xff1a T gt V gt B 三 挖空后的效果
  • STL初识

    STL的诞生 长久以来 xff0c 软件界一直希望建立一种可重复利用的东西 C 43 43 的面向对象和泛型编程思想 xff0c 目的就是复用性的提升 大多情况下 xff0c 数据结构和算法都未能有一套标准 导致被迫从事大量重复工作 为了建
  • 删除U盘中的System Volume Information 文件夹的方法

    在使用U盘测试ARM板的时候 xff0c 会发现System Volume Information这个文件夹阴魂不散 xff0c 总是存在 xff0c 在Windows下是看不见的 xff0c 即便将文件的查看属性设置为显示隐藏文件 在使用
  • Linux命令发送Http的get或post请求

    get请求 curl命令模拟get请求 xff1a 1 使用curl命令 xff1a curl span class hljs string 34 http www baidu com 34 span 如果这里的URL指向的是一个文件或者一
  • 深度学习之----多任务学习

    介绍 在机器学习 xff08 ML xff09 中 xff0c 通常的关注点是对特定度量进行优化 xff0c 度量有很多种 xff0c 例如特定基准或商业 KPI 的分数 为了做到这一点 xff0c 我们通常训练一个模型或模型组合来执行目标
  • PID控制原理(全干货)

    主要内容 xff1a 1 常用的控制算法与PID控制算法的异同点 xff1b 2 PID控制算法的理论分析 3 基于单片机的PID算法实现 4 PID算法的工程应用的一些注意事项 5 演示板电路分析 6 PID算法C语言实现 基于ARM C
  • ESP32 手册+文档整理

    ESP32 一些手册和批注 Arduino IDE 这个板子是带了LoRa的版本 xff0c 国外还有一个TTGo 有类似的ESP32 43 LoRa这种组合 如果不需要LoRa xff0c 可以考虑ESP32 DevKit 或者PicoK
  • 【TVM帮助文档学习】TVM语言参考

    本文翻译自Language Reference tvm 0 9 dev0 documentation 本文档提供TVM的嵌入式语言和IRs的参考 Relay介绍 Relay 是一种函数式的 可微的编程语言 它是一种面对机器学习领域的具有良好
  • 【TVM帮助文档学习】通过示例分析TVM代码流程

    本文翻译自TVM Codebase Walkthrough by Example tvm 0 9 dev0 documentation 了解TVM代码颇具挑战性 xff0c 它的各组件之间的交互非常隐晦 在本指南中 xff0c 我们将通过一
  • Linux设置nacos自启动(centos7)

    1 编写服务脚本 vim lib systemd system nacos service 将下列内容添加进入 span class token punctuation span Unit span class token punctuat
  • 图像处理——Haar特征

    Haar特征最初是用来进行人脸特征的表示的 xff0c 最近重新看了SURF算法 xff0c 发现在生成特征点描述子的时候也有用到Haar特征 查看了一些博文 xff0c 自己整理一些 xff0c 方便以后复习 Haar特征分为三类 xff
  • TVM运行时系统

    本文翻译自TVM Runtime System tvm 0 9 dev0 documentation TVM的编译器栈开发和部署支持多种编程语言 在本文中 xff0c 我们将解释TVM运行时的关键元素 我们需要满足一些有趣的需求 部署 从p
  • 彻底解决anaconda虚拟环境中pip是全局pip 下载包自动到base环境而非虚拟环境的问题 No module named _abc报错解决

    删除系统变量中的 PYTHONHOME C ProgramData Anaconda3 同时需要将虚拟环境的Lib site package的路径添加至系统变量Path中 xff0c 否则还是会报没有 abc模块的错误
  • C++基础语法

    C语言作为程序化的开发语言 xff0c 适合处理较小规模的程序 xff0c 相对于大规模程序 xff0c C语言并不合适 xff0c 所以提出了C 43 43 语言 C 43 43 对C语言的加强主要表现在 1 命名空间 2 函数重载与运算
  • 什么是DOM对象?如何获取DOM对象?

    今天的web前端培训环节 xff0c 我们讲解一下DOM对象 DOM对象本质上是浏览器根据html标签生成的 JS对象 xff0c 它的所有的标签属性都可以在这个 JS对象上面找到 xff0c 修改这个对象的属性会自动映射到标签身上 DOM
  • 2021电赛F题数字识别和巡线部分

    文章之前12月发了一次 xff0c 但是我后来申请的免毕设后 xff0c 用到了一些文字 xff0c 所以删了这篇文章 xff0c 但是还是查重了 xff0c 于是我把一些程序讲解先删了 xff0c 等毕设结束后再编辑加上 这次电赛我没有准