OpenMV 2022电赛泊车视觉方案解析

前言

作者第一次参加电赛,也是第一次接触OpenMV,通过几天的学习完成了对车库以及边线巡线的视觉识别方案,分享出来希望能提供一些思路给其他使用OpenMV的朋友。

效果展示

车库T型连接处识别:

车库T型连接处识别

巡线的效果忘记截图了,不过代码里有,感兴趣的朋友可以跑一下试试。

识别思路

本项目主要使用了OpenMV提供的find_blobs()函数,具体的使用方法可以查看官方教程
通过对被场地上黑线分割出来的白色区域进行识别,可以简单有效的识别出车库接缝。首先提取画面中所有的色块,将画面平均分为上下两个部分,以分类上下两种色块。当未到达车库连接处时,画面中仅有一条黑线,画面将被分割为上下两个部分,上下各一块。当画面中出现车库接缝时,将被分割为上面两块,下面一块,通过对上下色块数量的检测,即可简单有效的识别出车库接缝。通过计算经过车库接缝的数量,并使用当前接缝坐标进行校准,即可确认小车当前的准确位置。
巡线部分将画面左侧较窄的部分提取了roi,同时提取黑线色块,并返回其中心坐标供单片机进行闭环,确保在行进过程中与车库距离保持恒定。

完整代码

import sensor, image, time, pyb

# 串口通信
uart = pyb.UART(3,115200,timeout_char = 1000)#串口初始化

threshold1 = (80, 200)#阈值
threshold2 = (0, 40)#阈值

sensor.reset()
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.set_framesize(sensor.QVGA)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False) # 关闭增益(色块识别时必须要关)
sensor.set_auto_whitebal(False) # 关闭白平衡
clock = time.clock()#定义时钟对象clock

# 串口输出变量
out_str1 = ''

T_time = 0
real_time = 0
now_T = False

line_roi = (0,50,40,240)


while(True):
    #clock.tick()#返回以毫秒计的通电后的运行时间。
    img = sensor.snapshot().lens_corr(1.5)

    blob_up = []
    blob_down = []
    largest_blob = []

    line_blob=img.find_blobs([threshold2], roi=line_roi, merge=True,pixels_area=50)
    if line_blob:#如果找到了颜色块
       # Find the blob with the most pixels.
       largest_blob.append(max(line_blob, key=lambda b: b.pixels()))
       # 绘制色块边缘会影响到之后的识别,调参结束请注释
       img.draw_rectangle(largest_blob[0].rect())#画矩形框 blob.rect() ---> 返回一个矩形元组(可当作roi区域)
       img.draw_cross(largest_blob[0].cx(), largest_blob[0].cy())#画十字 blob.cx(), blob.cy() --->返回中心点x和y坐标


    #img.find_blobs()查找图像中所有色块,并返回包含每个色块的色块对象列表
    for blob in img.find_blobs([threshold1], pixels_threshold=200, area_threshold=200, merge=True):
    #若一个色块的边界框区域小于 area_threshold ,则会被过滤掉。
    #若一个色块的像素数小于 pixel_threshold ,则会被过滤掉。
    #merge_cb 可设置为用以调用两个即将合并的色块的函数,以禁止或准许合并。
        img.draw_rectangle(blob.rect())#画矩形框 blob.rect() ---> 返回一个矩形元组(可当作roi区域)
        img.draw_cross(blob.cx(), blob.cy())#画十字 blob.cx(), blob.cy() --->返回中心点x和y坐标

        if blob.cy() >120:
            blob_down.append(blob)
        else:
            blob_up.append(blob)

    #检测T
    if len(blob_up) == 2 and len(blob_down) == 1:
        now_T = True
        #print('T')

    else:
        now_T = False

    #判断过了几个T
    if now_T == True:
        real_time+=1 #滤波
        if real_time==5:
            T_time+=1
    else:
        real_time=0

    out_str1 += 's';  # 校验用,可以注释掉
    out_str1 += '%.d' % int(now_T);  # 当前是否有T
    out_str1 += '%.d' % int(T_time);  # T个数
    if largest_blob:
       out_str1 += '%.d' % int(largest_blob[0].cy());  # 与车库距离,用来巡线

    # 发送
    uart.write(out_str1)

    print(now_T)
    print(out_str1);

    # 串口数组清零
    out_str1 = ''    # 清除之前的数据

    #print(clock.fps())#clock.fps() ---> 停止追踪运行时间,并返回当前FPS(必须先调用tick)。

如果文章有帮助到你,请给我点个赞,谢谢!

物联沃分享整理
物联沃-IOTWORD物联网 » OpenMV 2022电赛泊车视觉方案解析

发表评论