1. はじめに

こんにちは、日本アドシスです。
当社は、福島県中通り(須賀川市)に本社を構えるソフトウェア開発会社です。2019年より「産学連携ロボット研究開発支援事業」において、会津大学と屋内搬送ロボットに関する研究開発を進めております。ここでは、本年度の研究開発で利用しておりますAprilTagと呼ばれるARマーカの検出方法についてご紹介します。

2. 環境

OS:Windows11
言語:Python3
主要ライブラリ:
 AprilTag(AprilRobotics · GitHub)
 pupil_apriltags(GitHub - pupil-labs/apriltags: Python bindings for the apriltags3 library · GitHub)

3. 必要なライブラリのインストール

ターミナルにて以下のコマンドを実行して必要なライブラリをインストールしてください。

python -m pip install --upgrade pip
pip install Pillow
pip install numpy
pip install opencv-python
pip install pupil-apriltags

4. AprilTagの生成について

公式が画像セットを公開しているので、そちらを使用していきます。以下のコマンドを実行してクローンしてください。

git clone https://github.com/AprilRobotics/apriltag-imgs.git

公式が公開しているマーカはサイズが非常に小さいです。そのため、付属のスクリプトを使用してサイズを変更したSVGファイルを作成します。
以下コマンドではtag36h11ファミリーのID0のマーカを20mmで作成します。作成したマーカは印刷して使用します。

python .\apriltag-imgs\tag_to_svg.py .\apriltag-imgs\tag36h11\tag36_11_00000.png tag36_11_00000.svg --size=20mm

図1  tag36_11_00000.svg

5. サンプルコード

import cv2
import numpy as np
from pupil_apriltags import Detector

def recognize_apriltag():
    cap = cv2.VideoCapture(0) # カメラの指定
    april_detector = Detector(families='tag36h11') #検出器の設定
    
    if not cap.isOpened():
        print('Camera not found.')
        return

    while True:
        ret, image = cap.read()
        if not ret:
            break

        # グレースケール化
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        # apriltagの検出
        tags = april_detector.detect(gray)

        if tags:
            # 検出したAprilTagを表示
            for tag in tags:
                tag_id = tag.tag_id
                center = tag.center.astype(np.int32)
                corners = tag.corners[::-1].astype(np.int32) # 左上から時計回りに並び替え

                # タグの位置とIDを表示
                image = cv2.polylines(image, [corners], True, (0, 0, 255), 1, cv2.LINE_AA)
                cv2.putText(image, str(tag_id), (center[0] - 10, center[1] - 10), 
                                        cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2, cv2.LINE_AA)

                # コーナー番号表示
                for i, corner in enumerate(corners):
                    x = corner[0]
                    y = corner[1]

                    cv2.circle(image, (x, y), 4, (0, 255, 0), -1)
                    cv2.putText(image, str(i), (x + 5, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (255, 0, 0), 2, cv2.LINE_AA)

        # 描画
        cv2.imshow('RecognizeApriltag', image)

        key = cv2.waitKey(1)
        if key == 27: #Escキー押下時に終了
            break

    # リソースの開放
    cap.release()
    cv2.destroyAllWindows()

if __name__ == '__main__':
    recognize_apriltag()

6. AprilTag検出方法

以下のコマンドでサンプルコードを実行してください。ここではサンプルコードをrecognize_apriltag.pyとして保存したものとします。

python .\recognize_apriltag.py

コンピュータに複数のカメラが接続されている場合は、以下のカメラの指定をする箇所の番号を変更することで異なるカメラから映像を取得することができます。

   cap = cv2.VideoCapture(0) # カメラの指定

pupil_apriltagsで検出されたAprilTagのコーナー順序は左下、右下、右上、左上となっております。
こちらを左上、右上、右下、左下の順に並び替えています。

                corners = tag.corners[::-1].astype(np.int32) # 左上から時計回りに並び替え

使用するライブラリによってコーナー順序は異なります。今後、AprilTagを使用して姿勢推定を実施する場合はコーナー順序にご注意ください。
サンプルコードの実行結果は図2のようになります。プログラムを終了する場合はESCキーを押下してください。


図2 サンプルコード実行結果

このようにAprilTagを検出することができました。図2の右側のAprilTagは向きを回転させているのですが、正しいコーナー順序を取得し、表示できていることが分かります。

7. 最後に

今回ご紹介する内容には含まれておりませんが、AprilTagを使用することでカメラ(ロボット)の相対位置や姿勢を推定することができるようになります。当社ではカメラとAprilTagを用いて得られた位置情報をロボットの自己位置推定に組み入れることで、自己位置喪失時の自己位置推定の精度向上を目指しています。
市場に向けては、これまでのソフトウェア技術を活用頂けるロボット開発企業様を募集しております。ご興味のある企業様がおられましたら、お気軽にお声がけ頂ければと思います。

株式会社日本アドシス
研究開発担当:佐浦