opencv/openmv识别三角形思路(识别多边形)

识别三角形

    • Canny算子和霍夫变换
    • 检测思路
    • 求两直线交点
    • 具体实现思路

Canny算子和霍夫变换

Canny算子主要用于边缘检测,霍夫变化则用于获取边缘直线。故我们先进行Canny边缘检测,后用霍夫变化。在opencv和openmv都有相关集成的函数,直接调用即可。

检测思路

霍夫变换之后会得到直线的两个点,我们可以运用这两个点求得直线的斜率(k)和截距(b)。再运用高中的知识便轻而易举的得到直线相交的点,以此为基础来判断图形的形状或进行其他运算。

求两直线交点

先求得直线的k和b,其中temp为直线的两个点。[x1,y1,x2,y2]。

def line_feature(temp):
    if temp[2] - temp[0] == 0: #防止分母为0报错
        k =0
    else:
        k = (temp[3] - temp[1]) / (temp[2] - temp[0])
    b = temp[1] - k * temp[0]

    return (k,b)

再求两直线的交点,其中temp_all存放的是两条不同直线的k、b。temp_all = [(k1,b1),(k2,b2)]。这里设n = 0,m =1。

def x_y(n:int, m :int):
    if (temp_all[m][0]-temp_all[n][0]) == 0: #防止分母为0报错
        x =0
    else:
        x = (temp_all[m][1] - temp_all[n][1]) / (temp_all[n][0]-temp_all[m][0])  #x = (b_2 - b_1)/(k_2-k_1)
    y = temp_all[n][0]*x + temp_all[m][1]                                  #y = k_1 * x + b_1

    return x,y

具体实现思路

ROI:感兴趣区,即你给图像设定一个方框,在这个方框内进行识别任务。
1、以openmv为例,利用for循环在特定的ROI(否则干扰太大)中遍历所有直线。
2、判断直线的数量是否等于三(三角形三边),在求得三个交点,判断是否都在我们事先设定好的ROI中。如果是则判断为三角形,否则不是三角形。
3、三个交点意味着有两条直线要重复用到,我们写个简单的算法实现改功能。

    if i == 3:        #判断是否有三条直线
        for n in range(3): 
            if n == 2:
                x, y = x_y(0, 2)       #得到第三个交点
            else:
                x, y = x_y(n, n+1)  #分别得到三条直线的得到两交点
            x = int(x)   #转化为整数,否则报错
            y = int(y)
            if (0<x<320 and 0<y<240):     #判断是否在我自己设定的ROI中
                img.draw_cross(x,y, color=(0,255,0), size=5,thickness=2)   #画出交点

这是最后的效果图
opencv/openmv识别三角形思路(识别多边形)_第1张图片
更新:上诉的检测思路大致是可行的,但是若想要落到实地,那还是缺少许多东西。以下例举出几个实际问题,并给出解决思路。
问题一:检测背景太复杂,导致无法正确检测出三角形边缘
解决方案:用二值化,代码参考如下

        img = sensor.snapshot()
        img.binary([color],invert=False)  #color是LAB的元组

问题二:三角形的交接点在可视范围之外,由于两不平行直线总会相交的特性,无论怎么检测都能检测都有交接点。
解决:用if进行判断,只选取在可视范围内的交接点。代码参考如下:

 if (0<=x<=160 and 0<=y<=120):  #160120是根据摄像头分别率调整的
img.draw_cross(x,y, color=(255,0,0), size=5,thickness=2) #其中x,y代表交接点

问题三:两直线垂直则出现x或y等于0的情况,导致无法准确划出交接点。
解决:没必要解决,交界点划在边缘也无所谓,你系统已经检测出三角形了,画只是一个可视化手段而已。
问题四:二值化之后再进行边缘检测,线太多。
解决:提高阈值即可。
问题五:OPENMV经常出现显存爆炸,运行中断。
解决:用try…except语句,检测错误便跳过这一帧,下一帧继续检测。并且注意用到的列表要在while循环末进行清空。

最后致各位看过本文章的同学:检测三角形只是我项目的一部分,完整的代码我很难单独拎出来献给各位。希望各位能在学习的路上耐下心来思考、理解,而不是生搬硬套别人的东西,我提供的只能是一个思路,具体如何整合到你们的项目中去,还需要大量发挥你们自己的智慧。

你可能感兴趣的:(Python,python,opencv)