K210 camera histogram coordinate recognition

The first hardware project I came into contact with was to design a simple intelligent vision car. My task in the project was to identify the coordinates of six target points on a piece of paper and send them to the car.

Figure 1 Site style

It is to identify the coordinates of the six points in the above picture and then transmit them to the car.

The recognition effect is probably like this:

 Figure 2 Recognition effect

Because it is the first time to do such a project, the first time I am not proficient in using maixpy, I hope you will forgive me, and the completion of the project meets expectations.

K210 camera uses special maixpyIDE for editing. It is written in the python language, but it feels that the indentation requirements are more stringent, and it will run incorrectly if it is not four-space indentation.

The first is to import:

import sensor,image,lcd,time

Import doesn't say anything, device, image, display, time, nothing else special import.

Then there is initialization, because I have never touched a hardware project before, initialization is a common initialization directly taken:

lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1)   #后置拍摄模式
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # 白平衡关闭
sensor.snapshot(1.8)#去鱼眼化

Then there is a function to find the largest color block:

def find_max(blobs): #找最大色块函数。这里是比较像素面积的方式,只返回最大面积色块
    max_size=0
    for blob in blobs:
        if blob[4] > max_size:
            max_blob=blob
            max_size = blob[4]
    return max_blob

Because the coordinate function only marks the pixel position, we need to mark the relative position according to the whole site. Here is the way to find the black line to find the whole site. Because there are too many black lines in the site, to mark the largest black color block, we need to write an output only function of the largest color patch. Here is to find the largest color block by comparing the number of pixels contained. blob[4] is the number of pixels.

To accurately identify the color, you need to find the color threshold accurately. You can find the color threshold through Tools - Machine Vision - Threshold Editor.

 Figure 3 Threshold Acquisition

Import the image file to adjust the threshold. When only the desired color is white, copy the threshold. The threshold recognized by the camera may be different from the real value. When debugging, it should be slightly changed within a certain range to make the camera more accurate.

 Figure 3 Threshold Editor

The item thresholds are:

green1_threshold   = (0, 55, -128, -18, 127, -18)
black_threshold  =(0, 46, -128, 15, -2, 44)

Then use find-blobs for color identification:

    blobs = img.find_blobs([black_threshold])#黑色边框定义识别
    blobs1 = img.find_blobs([green1_threshold])#绿色目标点定义

After that, the black border is identified and then calculated to calculate the pixel length of a unit length.

if blobs:        #寻找黑色边框
        max_blob = find_max(blobs)

        x1=max_blob[0]
        y1=max_blob[1]
        w1=max_blob[2]
        h1=max_blob[3]
        a1=(int((w1/2)+x1)-max_blob[0])/4
        a2=(int((h1/2)+y1)-max_blob[1])/4#计算单位坐标像素长度
        if a1==0:
            a1=1
        if a2==0:
            a2=1        #a1、a2之后要做分母,摄像镜头一开始找目标可能会出现0这里去零
        img.draw_rectangle(max_blob[0:4], color=(0,0,0))#对找到的目标进行黑框标注
        img.draw_cross(int((w1/2)+x1), int((h1/2)+y1))#使用十字标注目标中心点位置
        img.draw_string(max_blob[0],max_blob[1], (str(max_blob[0])+','+str(max_blob[1])), color = (0,0,0))#在显示屏标注目标最左和最下的坐标

The calculation unit length here is calculated according to the 8*8 site of the project. If you want to calculate the site of other specifications, the above code is complicated. It is roughly the length of the black frame max-blob divided by the site x number of grids. Here is the division Take eight.

Then look for the green target and calculate the target coordinates.

    if (blobs and blobs1):#寻找绿色目标点

        for b in blobs1:
            i=i+1
            x = b[0]
            y = b[1]
            width = b[2]
            height = b[3]




            if (x>=x1 and x<=x1+w1 and y>=y1 and y<=h1):
                c1=int(((b[5]-x1)+10)/a1)
                c2=int(((b[6]-y1)+10)/a2)#计算目标点坐标这里加10是摄像头有误差,我的加10最准确

                img.draw_rectangle([x,y,width,height])#用矩形标记出目标颜色区域
                t1[i-1]=8-abs(c1)
                t2[i-1]=8-abs(c2)#因为显示屏上图像是反转的,所以这里要用8减去。这里要看初始化跟不跟我的一样
                t=[t1[i-1],t2[i-1]]#形成数组,这就是目标点的坐标
                img.draw_cross(b[5], b[6]) #用十字标注目标中心点

It should be noted that when calculating the coordinates, it is necessary to continuously debug and add and subtract pixel values ​​to prevent large errors. Here, 10 pixel values ​​are added to the coordinates to accurately display the coordinates. Different devices may be different.

The latter includes de-duplicated data and display notes, which are relatively complete, and the complete code is directly posted here without explaining them one by one.

Full code:

import sensor,image,lcd,time
green1_threshold   = (0, 55, -128, -18, 127, -18)
black_threshold  =(0, 46, -128, 15, -2, 44)

#常用初始化
lcd.init()
sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QVGA)
sensor.set_vflip(1)   #后置拍摄模式
sensor.skip_frames(10) # Let new settings take affect.
sensor.set_auto_whitebal(False) # 白平衡关闭
sensor.snapshot(1.8)#去鱼眼化
def find_max(blobs): #找最大色块函数。这里是比较像素面积的方式,只返回最大面积色块
    max_size=0
    for blob in blobs:
        if blob[4] > max_size:
            max_blob=blob
            max_size = blob[4]
    return max_blob
i=0#循环计数
m=0#去除重复计数
t1=[0 for n in range(10000)]
t2=[0 for n in range(10000)]   #将t1和t2进行数组化,便于之后去重复数据
while True:
    img=sensor.snapshot()
    img = sensor.snapshot().lens_corr(strength = 1.2, zoom = 1.0)  #调整显示屏使其更“平整”便于识别,里面参数可更改
    blobs = img.find_blobs([black_threshold])#黑色边框定义识别
    blobs1 = img.find_blobs([green1_threshold])#绿色目标点定义


    if blobs:        #寻找黑色边框
        max_blob = find_max(blobs)

        x1=max_blob[0]
        y1=max_blob[1]
        w1=max_blob[2]
        h1=max_blob[3]
        a1=(int((w1/2)+x1)-max_blob[0])/4
        a2=(int((h1/2)+y1)-max_blob[1])/4#计算单位坐标像素长度
        if a1==0:
            a1=1
        if a2==0:
            a2=1        #a1、a2之后要做分母,摄像镜头一开始找目标可能会出现0这里去零
        img.draw_rectangle(max_blob[0:4], color=(0,0,0))#对找到的目标进行黑框标注
        img.draw_cross(int((w1/2)+x1), int((h1/2)+y1))#使用十字标注目标中心点位置
        img.draw_string(max_blob[0],max_blob[1], (str(max_blob[0])+','+str(max_blob[1])), color = (0,0,0))
        #在显示屏标注目标最左和最下的坐标
        if (max_blob[1]==0):#因为周围环境黑色较多,这里设置当黑色边框顶格时卡顿一下,调整摄像头恢复
            continue

    if (blobs and blobs1):#寻找绿色目标点

        for b in blobs1:
            i=i+1
            x = b[0]
            y = b[1]
            width = b[2]
            height = b[3]




            if (x>=x1 and x<=x1+w1 and y>=y1 and y<=h1):
                c1=int(((b[5]-x1)+10)/a1)
                c2=int(((b[6]-y1)+10)/a2)#计算目标点坐标这里加10是摄像头有误差,我的加10最准确

                img.draw_rectangle([x,y,width,height])#用矩形标记出目标颜色区域
                t1[i-1]=8-abs(c1)
                t2[i-1]=8-abs(c2)#因为显示屏上图像是反转的,所以这里要用8减去。这里要看初始化跟不跟我的一样
                t=[t1[i-1],t2[i-1]]#形成数组,这就是目标点的坐标
                img.draw_cross(b[5], b[6]) #用十字标注目标中心点
            
                n=0
                j=0

                while j<i: #防重复
                    if (t1[i-1]==t1[j-1] and t2[i-1]==t2[j-1]):
                        n=i+1
                    j=j+1
                if (n==0 and (abs(t1[i-1])<9)):#这里是对点进行输出,重复点不输出
                    print(t)
                    m=m+1#计数,记录输出几个点
                img.draw_string(x,y, "x")#标注文本x、y
                img.draw_string(x+10, y, str(t))#标注坐标
                img.draw_string(x,y+20, "green")#标注文本green如果是其他颜色请更改

    lcd.display(img)#lcd屏幕显示

Guess you like

Origin blog.csdn.net/qq_54034196/article/details/128509164