OpenMV教程:使用形状识别进行图像处理

矩形识别
Rect.py

# Find Rects Example
#
# 这个例子展示了如何使用april标签代码中的四元检测代码在图像中找到矩形。 四元检测算法以非常稳健的方式检测矩形,并且比基于Hough变换的方法好得多。 例如,即使镜头失真导致这些矩形看起来弯曲,它仍然可以检测到矩形。 圆角矩形是没有问题的!
# (但是,这个代码也会检测小半径的圆)...

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # 灰度更快(160x120 max on OpenMV-M7)
sensor.set_framesize(sensor.QQVGA)#160 * 120
sensor.skip_frames(time = 2000)
clock = time.clock()

while(True):
    clock.tick()
    img = sensor.snapshot()

    # 下面的`threshold`应设置为足够高的值,以滤除在图像中检测到的具有
    # 低边缘幅度的噪声矩形。最适用与背景形成鲜明对比的矩形。

    #find_rects只有两个参数roi(x,y,w,h) + threshold
    #如果只想显示图像右下角位置,则roi=(80,60,80,60)
    for r in img.find_rects(threshold = 20000):                                         
               #rect.rect()返回一个矩形元组(x, y, w, h),用于如矩形的边界框的image.draw_rectangle()等其他的 image 方法。
        
        img.draw_rectangle(r.rect(), color = (255, 0, 0))
        #image.draw_rectangle(x, y, w, h[, color[, thickness=1[, fill=False]]])在图像上绘制一个矩形。
            # 您可以单独传递x,y,w,h或作为元组(x,y,w,h)传递。
            #color 是用于灰度或RGB565图像的RGB888元组。默认为白色。但是,您也可以传递灰度图像的基础像素值(0-255)或RGB565图像的字节反转RGB565值。
            #thickness 控制线的粗细像素。
            #将 fill 设置为True以填充矩形。
            
        #rect.corners()
        #返回一个由矩形对象的四个角组成的四个元组(x,y)的列表。四个角通常是按照从左上角开始沿顺时针顺序返回的。
        
        #嵌套循环!rect.corners()返回一个由矩形对象的四个角组成的四个元组(x,y)的列表。四个角通常是按照从左上角开始沿顺时针顺序返回的。
        for p in r.corners(): img.draw_circle(p[0], p[1], 5, color = (0, 255, 0))  #在四个角上画圆 
            #image.draw_circle(x, y, radius[, color[, thickness=1[, fill=False]]])
            #在图像上绘制一个圆形。与上方draw_rects()类似
        
        print(r)

    print("FPS %f" % clock.fps())


#rect.x()返回矩形的左上角的x位置。您也可以通过索引 [0] (如上方r[0])取得这个值。
#rect.y()返回矩形的左上角的y位置。您也可以通过索引 [1] (如上方r[1])取得这个值。
#rect.w()返回矩形的宽度。您也可以通过索引 [2] (如上方r[2])取得这个值。
#rect.h()返回矩形的高度。您也可以通过索引 [3] (如上方r3])取得这个值。
#rect.magnitude()返回矩形的模(magnitude)。您也可以通过索引 [4] (如上方r[4])取得这个值。

圆形识别
Circle.py

# 圆形检测例程
#
# 这个例子展示了如何用Hough变换在图像中找到圆。
# https://en.wikipedia.org/wiki/Circle_Hough_Transform
#
# 请注意,find_circles()方法将只能找到完全在图像内部的圆。圈子之外的
# 图像/ roi被忽略...

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # 灰度更快
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()

while(True):
    clock.tick()

    #lens_corr(1.8)畸变矫正
    img = sensor.snapshot().lens_corr(1.8)      #如果采用的是无畸变镜头可以注释掉

    # Circle对象有四个值: x, y, r (半径), 和 magnitude。
    # magnitude是检测圆的强度。越高越好

    # roi 是一个用以复制的矩形的感兴趣区域(x, y, w, h)。如果未指定,
    # ROI 即图像矩形。操作范围仅限于roi区域内的像素。

    # x_stride 是霍夫变换时需要跳过的x像素的数量(仅查找在x方向上大于x_srtide的圆)。若已知圆较大,可增加
    # x_stride 。

    # y_stride 是霍夫变换时需要跳过的y像素的数量(仅查找在y方向上大于y_srtide的圆)。若已知直线较大,可增加
    # y_stride 。

    # threshold 控制从霍夫变换中监测到的圆。只返回大于或等于阈值的圆。
    # 应用程序的阈值正确值取决于图像。注意:一条圆的大小是组成圆所有
    # 索贝尔滤波像素大小的总和。

    # x_margin 控制所检测的圆的合并(如果这两个圆在x方向上的距离小于x_margin个像素点就合并)。 圆像素为 x_margin 、 y_margin 和  
    # r_margin的部分合并。

    # y_margin 控制所检测的圆的合并(如果这两个圆在y方向上的距离小于y_margin个像素点就合并)。 圆像素为 x_margin 、 y_margin 和
    # r_margin 的部分合并。

    # r_margin 控制所检测的圆的合并(如果这两个圆在半径r方向上的距离小于r_margin个像素点就合并)。 圆像素为 x_margin 、 y_margin 和
    # r_margin 的部分合并。

    # r_min,r_max和r_step控制测试圆的半径。
    # 缩小测试圆半径的数量可以大大提升性能。
    # threshold = 3500比较合适。如果视野中检测到的圆过多(特别是有些杂乱的圆),请增大阈值;
    # 相反,如果视野中检测到的圆过少,请减少阈值。
    for c in img.find_circles(threshold = 5000, x_margin = 10, y_margin = 10, r_margin = 10,r_min = 2, r_max = 100, r_step = 2):
        img.draw_circle(c.x(), c.y(), c.r(), color = (255, 0, 0))
        print(c)

    print("FPS %f" % clock.fps())

直线识别
line.py

# 线段检测例程
#
# 这个例子展示了如何在图像中查找线段。对于在图像中找到的每个线对象,
# 都会返回一个包含线条旋转的线对象。

# find_line_segments()找到有限长度的线(但是很慢)。
# Use find_line_segments()找到非无限的线(而且速度很快)。

enable_lens_corr = False # 关闭畸变矫正(进行畸变矫正会使图像帧率降低),追求准确度的话可以打开打开以获得更直的线条…

import sensor, image, time

sensor.reset()
sensor.set_pixformat(sensor.RGB565) # 灰度更快
sensor.set_framesize(sensor.QQVGA)
sensor.skip_frames(time = 2000)
clock = time.clock()

# 所有线段都有 `x1()`, `y1()`, `x2()`, and `y2()` 方法来获得他们的终点
# 一个 `line()` 方法来获得所有上述的四个元组值,可用于 `draw_line()`.

while(True):
    clock.tick()
    img = sensor.snapshot()
    if enable_lens_corr: img.lens_corr(1.8) # 如果打开了畸变矫正那么就进行畸变矫正

    # `merge_distance`控制附近行的合并。 在0(默认),没有合并。 
    # 在1处,任何距离另一条线一个像素点的线都被合并...等等,
    # 因为你增加了这个值。 您可能希望合并线段,因为线段检测会产生大量
    # 的线段结果。

    # `max_theta_diff` 控制要合并的任何两线段之间的最大旋转差异量。
    # 默认设置允许15度。

    for l in img.find_line_segments(merge_distance = 0 ,max_theta_diff = 5):
                                    #merge_distance指两条线段之间可以被相互分开而不被合并的最大像素数,设置为0就默认不合并
                                                         #max_theta_diff指如果两条线段要合并的话(前提),如果角度差小于max_theta_diff,那么两条直线将被合并
        img.draw_line(l.line(), color = (255, 0, 0))
        # print(l)

    print("FPS %f" % clock.fps())
    
#调用img.find_line_segments()返回的对象
#line.line()返回一个直线元组(x1, y1, x2, y2) ,用于如 image.draw_line 等其他的 image 方法。
#line.x1()返回直线的p1顶点 x坐标分量。您也可以通过索引 [0] 取得这个值。
#line.y1()返回直线的p1 y分量。您也可以通过索引 [1] 取得这个值。
#line.x2()返回直线的p2 x分量。您也可以通过索引 [2] 取得这个值。
#line.y2()返回直线的p2 y分量。您也可以通过索引 [3] 取得这个值。
#line.length()返回直线长度即 sqrt(((x2-x1)^2) + ((y2-y1)^2).您也可以通过索引 [4] 取得这个值。
#line.magnitude()返回霍夫变换后的直线的模(magnitude)。您也可以通过索引 [5] 取得这个值。
#line.theta()返回霍夫变换后的直线的角度(0-179度)。您也可以通过索引 [7] 取得这个值。
    #可以用于判断图像是不是三角形!详细见例程


#line.rho()返回霍夫变换后的直线p值。您也可以通过索引 [8] 取得这个值。    
物联沃分享整理
物联沃-IOTWORD物联网 » OpenMV教程:使用形状识别进行图像处理

发表评论