基于Openmv H7 Plus 的红色巡线+十字路口+多数字识别算法

一、串口通信

由于是采用命令集的方式控制openmv,摄像头不需要接收太多的数据,我采用的是判断串口接收的长度来区分命令集。flag为接收数据的长度,通过发送不同长度数据来改变openmv的工作模式

一、色块识别巧用

1.巡线

在openmv的开源库中有色块识别的关键函数blob(),可以传回识别出的矩形色块的中心坐标blob.cx() blob.cy()和色块宽度blob.w()及高度blob.h() ,及色块偏转角度.

在巡线过程中可以通过传回色块中心坐标和角度来判断当前的姿态是否需要矫正,可通过其他处理器中的pid矫正。

2.十字/T字识别

想必你也能猜到我要用什么来判断十字/T字路口了,那就是通过判断blob.w()即色块宽度来判断是否到达路口,当blob.w()大于一定阈值时,即可判断为十字路口。

3.数字识别

openmv的开源资料很多,其中能用于数字识别的常用的就是神经网络和模板匹配,由于我的摄像头是openmv H7 Plus ,因此选择采用神经网络的方法来作数字识别,建立出来的模型的准确率也极高,只要不是特殊刁钻的角度,均可使用。

(本来是100%的,被我改没了=-=)

 

 4.多数字识别左右判断

图像识别处理的核心就是滤除图像噪音,排除无用的部分。我们可以先截取图像中识别到的矩形数字框,再对矩形数字框进行神经网络的数字识别。这样就排除了很多图像噪音,提高了很多准确率。

为了提高手持数字的成功率,我建立了两套的模型labels1和labels分别来对手持数字、地面数字进行识别。(labels1的数字识别是采用特殊角度进行的,建议你们采用自己建立模型)

具体代码如下

(代码是电赛期间敲的,最近也忙,备注懒得打了=-=,有的备注)

# Edge Impulse - OpenMV Image Classification Example

import sensor, image, time, os, tf,math
from pyb import UART

sensor.reset()                         # Reset and initialize the sensor.
sensor.set_pixformat(sensor.GRAYSCALE)    # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA)      # Set frame size to QVGA (320x240)
sensor.set_windowing((320, 240))       # Set 240x240 window.
sensor.skip_frames(time=2000)          # Let the camera adjust.
threshold_index = 0 # 0 for red, 1 for green, 2 for blue

# Color Tracking Thresholds (L Min, L Max, A Min, A Max, B Min, B Max)
# The below thresholds track in general red/green/blue things. You may wish to tune them...
thresholds = [(70, 4, 18, 127, -125, 127), # generic_red_thresholds
              (30, 100, -64, -8, -32, 32), # generic_green_thresholds
              (0, 30, 0, 64, -128, 0)] # generic_blue_thresholds

uart = UART(3, 115200)

net = "trained.tflite"
labels = [line.rstrip('\n') for line in open("labels.txt")]
net1 = "trained1.tflite"
labels1 = [line.rstrip('\n') for line in open("labels1.txt")]
crosstime=0
clock = time.clock()
aa=[0,0,0,0,0,0]
num=10
roi=(0,0,0,0)
flag=10#4识别数字 5巡线     6匹配数字  1继续寻找 0找到数字
direct=0        #第一个数据判断左右 0直行 1左拐 2右拐
while(True):
    clock.tick()
    size = uart.any();
    if size != 0:
        command = " "
        command = uart.read()
        flag = len(str(command))
        size = 0
        print(flag)

    while(flag==4):#######################2初始复位识别数字
        img = sensor.snapshot().lens_corr(1.8)
        if 1:




    # default settings just do one detection... change them to search the image...
            for obj in tf.classify(net1, img, min_scale=1.0, scale_mul=0.8, x_overlap=0.5, y_overlap=0.5):
                img.draw_rectangle(obj.rect())
        # This combines the labels and confidence values into a list of tuples
                predictions_list = list(zip(labels1, obj.output()))

                for i in range(len(predictions_list)):
                    if  predictions_list[i][1]>0.95:
                        num=i+1
                        output_str="[%3.d,%3.d]" % (num,7)################################
                        uart.write(output_str)########################################
                        print(output_str)
                        flag=5


    if(flag==5):
        sensor.set_pixformat(sensor.RGB565)
        img = sensor.snapshot().lens_corr(1.8)
        found=0
        for blob in img.find_blobs([thresholds[threshold_index]], pixels_threshold=200, area_threshold=200, merge=True):
        # These values depend on the blob not being circular - otherwise they will be shaky.
            if blob.elongation() > 0.5:
                img.draw_edges(blob.min_corners(), color=(255,0,0))
                img.draw_line(blob.major_axis_line(), color=(0,255,0))
                img.draw_line(blob.minor_axis_line(), color=(0,0,255))
        # These values are stable all the time.
            img.draw_rectangle(blob.rect())
            img.draw_cross(blob.cx(), blob.cy())
        # Note - the blob rotation is unique to 0-180 only.
            img.draw_keypoints([(blob.cx(), blob.cy(), int(math.degrees(blob.rotation())))], size=20)
        #print(blob.corners())
            found=1         #找到红线
            if blob.w()<250:
                output_str="[%3.d,%3.d]" % (blob.cx(),1) #巡线
            else:
                output_str="[%3.d,%3.d]" % (0,4) #十字      切换至数字寻找数字
        #print(blob.cx(),blob.w(),blob.rotation_deg())
        if found==0:
            output_str="[%3.d,%3.d]" % (0,6)  #没识别到红线则停车 保持巡线模式

        uart.write(output_str)#######################################################
        print(output_str)

    if(flag==6):
        sensor.set_pixformat(sensor.GRAYSCALE)
        img = sensor.snapshot().lens_corr(1.8)
        img1=img
        found=0
        output_str="[%3.d,%3.d]" % (0,5)
    # 下面的`threshold`应设置为足够高的值,以滤除在图像中检测到的具有
    # 低边缘幅度的噪声矩形。最适用与背景形成鲜明对比的矩形。
    #寻找第一个数字
        for r in img.find_rects(threshold = 10000):
            img.draw_rectangle(r.rect(), color = (255, 0, 0))
            for p in r.corners(): img.draw_circle(p[0], p[1], 5, color = (0, 255, 0))
            #print(r1.x(),r1.y(),r1.w(),r1.h())
            roi=[r.x(),r.y(),r.w(),r.h()]
            img1=img.copy(1,1,roi,True)

            #print(roi1)


            for obj1 in tf.classify(net, img1, min_scale=1.0, scale_mul=0.8, x_overlap=0.5, y_overlap=0.5):
                img1.draw_rectangle(obj1.rect())
                # This com  bines the  labels and confidence values into a list of tuples
                predictions_list = list(zip(labels, obj1.output()))
                if  predictions_list[num-1][1]>0.6:
                    found=1
                    print(num)
                    if  r.x()+r.w()/2<140:  #####左拐
                        output_str="[%3.d,%3.d]" % (1,5)
                    else:
                        output_str="[%3.d,%3.d]" % (2,5)

            uart.write(output_str)
            print(output_str)

  • 28
    点赞
  • 245
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OTITA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值