电赛F题 视觉openmv代码

2021年电赛 F题 视觉部分 (openMV4 plus)记录

记录下比赛

emmmm选了F题,别的都没思路,哈哈哈哈哈,对小车比较亲切

赛题一出,就确定了大概率是F题了,看了看题认为是“数字识别”+“巡线小车” 扩展部分的话就是“无线通信”+“路径规划(或者路线记忆?😂)”

刚开始是想把“地图数据”存在32里面:规划好每个病房路线,到时候通过摄像头识别并返回实际病房数字,与已规划路线匹配,这样回来的就更精准了。

以下部分摄像头仅负责1-8识别以及识别”病房虚线“
说说图像识别(openMV4 plus)

在edge impulse训练数字识别,很多人都是这么想的,但是在运动中不可行。帧率太低,跟不上反应。(此处可以使用停车识别数字)尽管显示98%正确率(数据集1800张,重拍数据集了好多次),但是考虑到环境等因素对其检测的不利因素,改用其他方案,当然有很多组是识别成功了的。
改为模板识别,采用灰度以提高帧率,识别效果还行,但是局限的是:摄像头角度、距离不能有太大变化,且处理8张照帧率真的很一般,行进中识别肯定不行。

根据赛道结构易知需对(“1”“2”)(“3”-“8”)不同处理,且需重点处理4位数

通过将各种情况模块化,将计算量分散,帧率上去了!

思路大概是这样:

“”"
先写个初始亮红灯
把1-8的图像遍历 # 用来识别目标值,帧率不需要很高
return 目标值
传回目标值到32
openmv判断目标值
灭红灯
进入对应模块(增加帧率)
传回转向方式到32
“”"
“”"
当aim为1或2时,将aim发送给stm32,使stm32在到达第一个路口时,直接进行左转或右转。
当aim为3-8时,进行行进中识别。
在行进中只对识别到2个或3个数(可补充4位数的情况)的情况进行处理(因为小车限高以及为保持识别准确率,摄像头的角度需要合理调整;由于同时匹配到4个数的概率很小(图像在边缘时匹配率较低),在匹配识别到3个数的时候就可以根据其相对位置判断左转还是右转)
“”"

组合调第一个车,速度与图像识别不可兼得,最后还好。

返回给32的是 目标值 和 行为指令(左,右,停)

之后时间就是双车链接,以不同目标位置把第二辆车的转向方式稍作修改以及其他…

当然用树莓派或别的平台处理效果更好

代码

匆忙写的,没有优化:无需停车识别数字,但仍有部分小问题
方案的缺陷在于摆放的数字需要紧挨在一起
{aim}
(1)左
(2)右
(3)停

import time, sensor, image, math, pyb
from image import SEARCH_EX, SEARCH_DS
from pyb import UART,LED
import json

# Reset sensor
sensor.reset()
# Set sensor settings
sensor.set_contrast(1)
sensor.set_gainceiling(16)
# Max resolution for template matching with SEARCH_EX is QQVGA
sensor.set_framesize(sensor.QQVGA)
# You can set windowing to reduce the search image.
#sensor.set_windowing(((640-80)//2, (480-60)//2, 80, 60))
sensor.set_pixformat(sensor.GRAYSCALE)

uart = UART(3,115200)
uart.init(115200,bits=8,parity=None,stop=1)

led1 = pyb.LED(1)
led2 = pyb.LED(2)



# Load template.
# Template should be a small (eg. 32x32 pixels) grayscale image.
template1 = image.Image("/1b.pgm")
template2 = image.Image("/2b.pgm")
template3 = image.Image("/3b.pgm")
template4 = image.Image("/4b.pgm")
template5 = image.Image("/5b.pgm")
template6 = image.Image("/6b.pgm")
template7 = image.Image("/7b.pgm")
template8 = image.Image("/8b.pgm")
template0 = image.Image("/s1.pgm")

clock = time.clock()

aim=0

flag=0	# 此变量没有用处

ma=[1,160,0,0]	# [数字值,x方向坐标,在屏幕左或右(1或2),是否被检测到(0或1)]
mb=[2,160,0,0]
mc=[3,160,0,0]
md=[4,160,0,0]
me=[5,160,0,0]
mf=[6,160,0,0]
mg=[7,160,0,0]
mh=[8,160,0,0]

def sum_list(items):	# 列表求和
    sum_numbers = 0
    for x in items:
        sum_numbers += x
    return sum_numbers	


def find_list(items,a):	# 用于查找已检测到的数
    itemss=[]
    for i in range(len(items)):
        if a in items:
            itemss.append(items.index(a)+i)
            items.pop(items.index(a))
    return itemss


def Tablefun(list):     #暂时用不到
    list_set = set(list)  
    frequency_dict = {}
    for i in list_set:  
        frequency_dict[i] = list.count(i)  # 创建dict; new_dict[key]=value
    grade_mode = []
    for key, value in frequency_dict.items():  # 遍历dict的key and value。key:value
        if value == max(frequency_dict.values()):
            grade_mode.append(key)
            break
    return grade_mode


def Temp_recogn1():	# 1-8,程序开始时对目标值的识别
    # Initial target recognition    # 待调roi # 待取众值
    template1 = image.Image("/kk1_70_.pgm")
    template2 = image.Image("/kk2_70_.pgm")
    template3 = image.Image("/kk3_70_.pgm")
    template4 = image.Image("/kk4_70_.pgm")
    template5 = image.Image("/kk5_70_.pgm")
    template6 = image.Image("/kk6_70_.pgm")
    template7 = image.Image("/kk7_70_.pgm")
    template8 = image.Image("/kk8_70_.pgm")
    kim = 0 # mean is stop
    mz=[0,159]	# 只要检测到数其x必然小于160,此处设置159是为了在没有识别到数字1-8时返回0 
    ma=[1,160]
    mb=[2,160]
    mc=[3,160]
    md=[4,160]
    me=[5,160]
    mf=[6,160]
    mg=[7,160]
    mh=[8,160]
    mk=[0,0,0,0,0,0,0,0,0]
    r1 = img.find_template(template1, 0.65, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r2 = img.find_template(template2, 0.63, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r3 = img.find_template(template3, 0.65, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r4 = img.find_template(template4, 0.67, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r5 = img.find_template(template5, 0.69, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r6 = img.find_template(template6, 0.67, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r7 = img.find_template(template7, 0.65, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r8 = img.find_template(template8, 0.67, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))

    if r1:
        img.draw_string(0,4,"1")
        ma[1]=r1[0]

    if r2:
        img.draw_string(0,15,"2")
        mb[1]=r2[0]

    if r3:
        img.draw_string(0,25,"3")
        mc[1]=r3[0]

    if r4:
        img.draw_string(0,35,"4")
        md[1]=r4[0]

    if r5:
        img.draw_string(0,55,"5")
        me[1]=r5[0]

    if r6:
        img.draw_string(0,65,"6")
        mf[1]=r6[0]

    if r7:
        img.draw_string(0,75,"7")
        mg[1]=r7[0]

    if r8:
        img.draw_string(0,85,"8")
        mh[1]=r8[0]

    nj=[mz,ma,mb,mc,md,me,mf,mg,mh]
    mk=sorted(nj,key=lambda x:x[1])	# 目的将数字以x坐标值大小排列
    ml=[a[0] for a in mk]			# 抓出排好序的数字

    print(mk)
    kim = ml[0]
    print(kim)						# kim是目标值,会传给aim
    return kim


def Temp_recog2(m0):	# 循环匹配3-8	m0为aim
    ma=[1,160,0,0]
    mb=[2,160,0,0]
    mc=[3,160,0,0]
    md=[4,160,0,0]
    me=[5,160,0,0]
    mf=[6,160,0,0]
    mg=[7,160,0,0]
    mh=[8,160,0,0]
    ml=[0,0,0,0,0,0,0,0]
    mm=[0,0,0,0,0,0,0,0]

    mlsum = 0			# 已识别到的数字数量
    r3 = img.find_template(template3, 0.66, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r4 = img.find_template(template4, 0.65, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r5 = img.find_template(template5, 0.67, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r6 = img.find_template(template6, 0.67, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r7 = img.find_template(template7, 0.65, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    r8 = img.find_template(template8, 0.66, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))

    if r3:
        img.draw_rectangle(r3)
        img.draw_string(0,25,"3")
        mc[2] = 1 if r3[0]+int(r3[2]*0.5) > 80 else 2
        mc[3] = 1

    if r4:
        img.draw_rectangle(r4)
        img.draw_string(0,35,"4")
        md[2] = 1 if r4[0]+int(r4[2]*0.5) > 80 else 2
        md[3] = 1

    if r5:
        img.draw_rectangle(r5)
        img.draw_string(0,55,"5")
        me[2] = 1 if r5[0]+int(r5[2]*0.5) > 80 else 2
        me[3] = 1

    if r6:
        img.draw_rectangle(r6)
        img.draw_string(0,65,"6")
        mf[2] = 1 if r6[0]+int(r6[2]*0.5) > 80 else 2
        mf[3] = 1

    if r7:
        img.draw_rectangle(r7)
        img.draw_string(0,75,"7")
        mg[2] = 1 if r7[0]+int(r7[2]*0.5)> 80 else 2
        mg[3] = 1

    if r8:
        img.draw_rectangle(r8)
        img.draw_string(0,85,"8")
        mh[2] = 1 if r8[0]+int(r8[2]*0.5) > 80 else 2
        mh[3] = 1

    mj=[ma,mb,mc,md,me,mf,mg,mh]    # 

    ml=[a[3] for a in mj]       # 判断是否检测到
    mm=[b[2] for b in mj]       # 方向列表
								
    mlsum=sum_list((ml))		# 已识别到的数字数量


    if (ml[m0-1] == 1)and(mlsum==2) :	# 识别到目标数且识别到两个数
        print(mm[m0-1])
        uart.write("({})".format(mm[m0-1])+"/r/n")
    elif (ml[m0-1] == 0)and(mlsum == 3):	# 未识别到目标数且识别到三个数
        kk=find_list(ml,1)
        kl=[mm[kk[0]],mm[kk[1]],mm[kk[2]]]
        if kl.count(1)==1:					# 方向判断
            print(1)
            uart.write("(1)"+"/r/n")

        else:
            print(2)
            uart.write("(2)"+"/r/n")

    else:
        print(0)



def Temp_stop():	# 匹配到虚线
    rs = img.find_template(template0, 0.70, step=4, search=SEARCH_EX) #, roi=(10, 0, 60, 60))
    if rs:
        uart.write("(3)"+"/r/n")
        print(3)


# Run template matching
while (True):
    clock.tick()
    img = sensor.snapshot()
    led1.on()
    while (True):
        img = sensor.snapshot()
        aim = Temp_recogn1()
        if aim:
            print("#########################")
            led1.off()
            uart.write("[{}]".format(aim)+"/r/n")
            led2.on()
            break

    # 加一个TEN
    print("[",aim,"]")
    if aim !=1:
        if aim != 2:
            while (True):
                img = sensor.snapshot()
                Temp_recog2(aim)
                time.sleep_ms(1200)		# 加时延,防误判(可用换s1.pgm解决)	
                Temp_stop()	# 无奖竞猜,这里的 bug 是什么
        else:
            time.sleep_ms(1200)
            Temp_stop()
    else:
        time.sleep_ms(1200)
        Temp_stop()
    led2.off()

# 写此文时有两个 bug 没做修正哦
# 在判断4位数后还应再进行一次2位数字的检测


  • 6
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值