OpenMV 2022 e-sports parking vision solution

foreword

It is the first time for the author to participate in the electric competition, and it is also the first time to contact OpenMV. After a few days of study, he completed the visual recognition scheme for the garage and sideline inspection . The sharing hope can provide some ideas for other friends who use OpenMV.

Show results

Garage T-junction identification:

Garage T-junction identification

I forgot to take a screenshot of the line patrol effect, but it is in the code, interested friends can try it out.

Identify ideas

This project mainly uses the find_blobs() function provided by OpenMV. For specific usage methods, please refer to the official tutorial .
By identifying the white area divided by the black line on the field , the garage joint can be easily and effectively identified. Firstly, all the color blocks in the picture are extracted, and the picture is evenly divided into upper and lower parts, so as to classify the upper and lower color blocks. When the junction of the garage is not reached, there is only one black line in the screen, and the screen will be divided into two parts, the upper and lower parts. When the garage seam appears in the screen, it will be divided into two upper parts and one lower part. By detecting the number of upper and lower color blocks, the garage seam can be easily and effectively identified. By counting the number of seams passed through the garage and calibrating with the current seam coordinates, the exact current position of the cart can be confirmed.
In the line inspection part, the roi is extracted from the narrower part on the left side of the screen, and the black line color block is extracted at the same time, and its center coordinates are returned for the single-chip microcomputer to close the loop to ensure that the distance from the garage remains constant during travel.

full code

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)。

If the article is helpful to you, please give me a like, thank you!

Guess you like

Origin blog.csdn.net/opklnmiojkbn/article/details/127364672