black_grayscale_line_following.py

# この作品はMITライセンスの下で提供されています。
# Copyright (c) 2013-2023 OpenMV LLC. 全著作権所有。
# https://github.com/openmv/openmv/blob/master/LICENSE
#
# 黒色グレースケールライントレースの例
#
# ライントレースロボットを作るには多くの労力が必要です。このサンプルスクリプトは
# ライントレースロボットのマシンビジョン部分を実装する方法を示します。
# このスクリプトの出力を使って差動駆動ロボットを制御し、
# ラインを追従させることができます。このスクリプトは単純に、
# ロボットを左右どちらに曲げるかを示す旋回値を1つ生成するだけです。
#
# このスクリプトを正しく動作させるには、カメラを45度程度の角度で
# ラインに向けてください。カメラの視野内にラインのみが入るようにしてください。
# (視野についての続き)

import csi
import time
import math

# 黒いラインを追跡します。白いラインを追跡するには[(128, 255)]を使用してください。
GRAYSCALE_THRESHOLD = [(0, 64)]

# 各roiは(x, y, w, h)です。ライン検出アルゴリズムは、各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の重みです。

# カメラのセットアップ……
csi0 = csi.CSI()
csi0.reset()  # カメラセンサーを初期化します。
csi0.pixformat(csi.GRAYSCALE)  # グレースケールを使用します。
csi0.framesize(csi.QQVGA)  # 速度のためQQVGAを使用します。
csi0.snapshot(time=2000)  # 新しい設定を反映させます。
csi0.auto_gain(False)  # カラートラッキングでは無効にする必要があります
csi0.auto_whitebal(False)  # カラートラッキングでは無効にする必要があります
clock = time.clock()  # FPSを計測します。

while True:
    clock.tick()  # snapshot()呼び出し間の経過ミリ秒を計測します。
    img = csi0.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:
            # 最もピクセル数の多いブロブを探します。
            largest_blob = max(blobs, key=lambda b: b.pixels)

            # ブロブの周りに矩形を描画します。
            img.draw_detection(largest_blob)

            centroid_sum += largest_blob.cx * r[4]  # r[4]はroiの重みです。

    center_pos = centroid_sum / weight_sum  # ラインの中心を求めます。

    # center_posを偏角に変換します。ラインから離れるほど反応が
    # 強くなるよう、非線形の演算を使用しています。このような
    # アルゴリズムの出力には、反応の「トリガー」を生じさせるために
    # 非線形演算を使うのが有効です。
    deflection_angle = 0

    # 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())  # 注: OpenMV Camは接続時、速度が約半分になります
    # コンピュータに接続されている間。切断するとFPSは向上します。

results matching ""

    No results matching ""