Openmv学习笔记(2)色块追踪应用实例——循线

循线视觉

        通过上一篇文章的学习,我们掌握了色块追踪的基本方法,进而可以尝试将方法投入实际应用,如循线视觉,原例的解释就非常不错,因此这里引用原例代码稍作补充:

import sensor
import time
import math

# 追踪黑线阈值,[(128, 255)] 可以追踪白线,若要减少干扰可以利用阈值编辑器进一步缩小区间
GRAYSCALE_THRESHOLD = [(0, 64)]


# 利用算法找到每个ROI内最大斑块的质心。随后,这些质心的x位置以不同权重进行平均计算,其中最大的权重分配给靠近图像底部的ROI(距离摄像头近),次之的权重给下一个ROI,依此类推。
ROIS = [  # [ROI, 权重]
    (0, 100, 160, 20, 0.7),  # 需要根据应用调整这些权重。
    (0, 50, 160, 20, 0.3),  # 根据机器人设置方式。
    (0, 0, 160, 20, 0.1),
]

# 计算权重除数(权重总和不是一定要等于1,这里是一种比例关系)。
weight_sum = 0
for r in ROIS:
    weight_sum += r[4]  # r[4]代表ROI权重。

# 摄像头配置中...
sensor.reset() 
sensor.set_pixformat(sensor.GRAYSCALE) 
sensor.set_framesize(sensor.QQVGA)  # 采用QQVGA分辨率以提升速度。
sensor.skip_frames(time=2000)  # 让新设置生效。
sensor.set_auto_gain(False)  
sensor.set_auto_whitebal(False) 
clock = time.clock()  # 跟踪FPS。

while True:
    clock.tick()  # Track elapsed milliseconds between snapshots().
    img = sensor.snapshot()  # 拍照并返回图像。

    centroid_sum = 0

    for r in ROIS:
        blobs = img.find_blobs(
            GRAYSCALE_THRESHOLD, roi=r[0:4], merge=True
        )  # r[0:4]为ROI区域元组。

        if blobs: # 防止屏幕中有roi无满足条件色块,导致largest_blob空值的情况
            # 寻找像素最多的色块。
            largest_blob = max(blobs, key=lambda b: b.pixels())  #lambda表达式

            # 在色块周围绘制矩形框。
            img.draw_rectangle(largest_blob.rect())
            img.draw_cross(largest_blob.cx(), largest_blob.cy())

            centroid_sum += largest_blob.cx() * r[4]  # r[4]代表ROI权重。

    center_pos = centroid_sum / weight_sum  # 确定线的中心。

    # 将center_pos转换为偏转角度。我们使用非线性
    # 操作,使得响应在我们偏离线越远时
    # 越强。非线性操作非常适合用于此类算法的输出
    # 以引发“触发”响应。
    deflection_angle = 0
c
    # 80来自X分辨率的一半,60来自Y分辨率的一半。
    # 下面的方程只是计算一个三角形的角度,其中
    # 三角形的对边是中心位置与中心的偏差,
    # 邻边是Y分辨率的一半。这将角度输出限制在
    # 大约-45到45之间。(并不完全是-45和45)。
    deflection_angle = -math.atan((center_pos - 80) / 60)

    # 将弧度转换为角度。
    deflection_angle = math.degrees(deflection_angle)

    # 现在你有了一个角度,告诉你需要转动机器人多少度
    # 包含离机器人最近的线部分以及离机器人较远的
    # 线部分,以获得更好的预测。
    print("Turn Angle: %f" % deflection_angle)

    print(clock.fps())  

        如果想要看到目前循线中心可以在centroid_pos = centroid_sum / weight_sum下添加,img.draw_cross(int(centroid_pos),60)

知识补充 :

        可以通过这位的博客了解一下lambda表达式:

python之lambda表达式 : 对于python中max函数的key参数的理解与使用_max ( key = lamdba )-CSDN博客https://blog.csdn.net/aic1999/article/details/79752435

详细解释:

        代码首先划定了三个roi区域并且设置了权重,其大概分布如下:

        对于每个设置权重的roi得到最大色块位置后,求出偏转中心,计算偏转角度。

         值得注意的是,增加ROIS的个数可以使得循线的判断更加细致精确。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值