[OpenCV]ArUcoマーカー検出のサンプルスクリプト


はじめに

OpenCVのARマーカーのライブラリArUcoのPython3サンプルスクリプトです

サンプルスクリプト

ソースをgithubにおきました。

参考リンク

準備

環境

Windows10,Python 3.8.6 を使いました。
ストリーミングを使う場合は、カメラモジュールを付けたRaspberry Pi 3 model Bを使いました。
ラズパイにはMJPEG-Streamerでストリーミングができるようにしています。

OpenCVインストール

Python3 が使える環境なら以下のコマンドでインストールすればOpenCVが使えるはずです。

$ pip install opencv-contrib-python

ARマーカー画像の作成

以下スクリプトを実行するとARマーカーが出力されます(ar.png)
githubのopcv_outputARmark02.pyを実行すると他のマーカーも出力できます。

opcv_outputARmark01.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import cv2
aruco = cv2.aruco
dictionary = aruco.getPredefinedDictionary(aruco.DICT_4X4_50)

def arGenerator():
    fileName = "ar.png"
    # 0: ID番号,150x150ピクセル
    generator = aruco.drawMarker(dictionary, 0, 150)
    cv2.imwrite(fileName, generator)
    img = cv2.imread(fileName)

arGenerator()

スクリプトの実行コマンド

$ python opcv_outputARmark01.py

出力されるマーカーar.pngです。

サンプルスクリプトの概要

githubに格納したデータの概要です。

ファイル名 検出対象 描画 出力
opcv_outputARmark01.py ARマーカー 画像
opcv_outputARmark02.py ARマーカー 画像
opcvCapImg01_drawID.py 画像 ID
opcvCapImg02_drawText.py 画像 文字
opcvCapImg03_drawLine.py 画像
opcvCapImg04_drawRectangle.py 画像 四角形
opcvCapImg05_drawCircle.py 画像
opcvCapImg06_drawPolylines.py 画像 多角形
opcvCapImg07_drawIMG.py 画像 画像
opcvCapImg08_drawAxis.py 画像 3D軸
opcvCapVideo01_drawID.py 動画 ID
opcvCapVideo02_drawID_outMP4.py 動画 ID 動画
opcvCapVideo03_drawRectangle_outMP4.py 動画 四角形 動画
opcvCapVideo04_drawText_outMP4.py 動画 文字 動画
opcvCapVideo05_drawAxis_outMP4.py 動画 3D軸 動画
opcvCapVideo06_drawImg_outMP4.py 動画 画像 動画
opcvCapVideo07_drawVideo_outMP4.py 動画 動画 動画
(dummy)test-mapping.mp4____.txt
(dummy)test-video.mp4____.txt
test-img01.png
test-img02.png
test-img03.png
test-mapping.png
  • カラム説明
    • 検出対象
      • ARマーカーを検出する対象
      • 画像
        • PNG形式の画像を使用します
      • 動画
        • 以下3種類の形式を含みます
            • MP4形式の動画
            • ストリーミング(ラズパイ+カメラ)
            • カメラデバイス(WindowsPC+カメラ)
    • 描画
      • 検出したARマーカーに付与する情報の種類
      • (ID, 文字, 画像, 動画 など)
    • 出力
      • 実行結果をファイル出力する形式
      • (画像, 動画)
  • ダミーファイル
  • 画像ファイル
    • ARマーカー検出用の画像
      • test-img01.png
      • test-img02.png
      • test-img03.png
    • マッピング用の画像
      • test-mapping.png

画像からマーカーを検出するスクリプト

[IMG-01] IDを描画:opcv_outputARmark01.py

aruco.drawDetectedMarkers(img, corners, ids, (0,255,0))で検出した全てのARマーカーに対し、IDとマーカーの4隅を頂点とした四角形を描画します。

[IMG-02] 文字を描画:opcvCapImg02_drawText.py

cv2.putText(・・・)で文字を描画します。サンプルではマーカーの4隅の座標を描画しました。

[IMG-03] 線を描画:opcvCapImg03_drawLine.py

cv2.line(・・・)で直線を描画します。

[IMG-04] 四角形を描画:opcvCapImg04_drawRectangle.py

cv2.rectangle(・・・)で四角形を描画します。

[IMG-05] 円を描画:opcvCapImg05_drawCircle.py

cv2.circle(・・・)で円を描画します。

[IMG-06] 多角形を描画:opcvCapImg06_drawPolylines_outImg.py

cv2.polylines(・・・)で多角形を描画します。

[IMG-07] 画像を描画

[IMG-08] 3D軸を描画

動画からマーカーを検出するスクリプト

※動画 test-video.mpを使用した実行結果を紹介します。

[VIDEO-01] IDを描画:opcvCapVideo01_drawID.py

マーカーを検出しIDを描画します。他の動画系のサンプルと違い結果を動画出力しません。

https://youtu.be/XVpjjGrzeAw

[VIDEO-02] IDを描画し動画ファイルを出力:opcvCapVideo02_drawID_outMP4.py

[VIDEO-01]と同様に、マーカーを検出しIDを描画します。


https://youtu.be/XVpjjGrzeAw

[VIDEO-03] 四角形を描画し動画ファイルを出力:opcvCapVideo03_drawRectangle_outMP4.py


https://youtu.be/eyuDafmZQ28

[VIDEO-04] 文字を描画し動画ファイルを出力:opcvCapVideo04_drawText_outMP4.py


https://youtu.be/zTJSGT5dQ_g

[VIDEO-05] 3D軸を描画し動画ファイルを出力:opcvCapVideo05_drawAxis_outMP4.py


https://youtu.be/nyaPeCBZ2hQ

[VIDEO-06] 画像を描画し動画ファイルを出力:opcvCapVideo06_drawImg_outMP4.py


https://youtu.be/1aR9-r7BFjQ

[VIDEO-07] 動画を描画し動画ファイルを出力:opcvCapVideo07_drawVideo_outMP4.py

検出したマーカーに動画ファイル(MP4)を描画します。出力した動画には、マーカーに合わせて描画した動画が含まれない(?)らしく、出力した動画には正しく描画されませんでした。


https://youtu.be/jqJlxl5lzkI

カメラデバイスやストリーミングを使用する場合

cv2.VideoCapture(・・・)は、カメラデバイスやMJPEG-Streamerにも対応しています。
cv2.VideoCapture(0)でカメラデバイスを、cv2.VideoCapture("http://{IP Address}:8090/?action=stream")でストリーミングを指定します。

以下の図のようにストリーミングに対しマーカー検出/描画ができるようになります。

ここの動画系のサンプルスクリプトで、カメラデバイス、ストリーミングが使用できることは確認しました。

ここのスクリプトでカメラデバイスやストリーミングを使う例を紹介します。opcvCapVideo07_drawVideo_outMP4.pyだと、以下に抜粋した変数targetVideo,outputVideoの値を変更すれば使用できます。

opcvCapVideo07_drawVideo_outMP4.py
# --- 抜粋 --- #

#targetVideo = 0 # カメラデバイス
#targetVideo = "test-video.mp4" # 動画
#targetVideo = "http://{IP Address}:8090/?action=stream" # MJPG-Streamer
targetVideo = "test-video.mp4"

#mappingVideo= 0 # カメラデバイス
mappingVideo= "test-mapping.mp4" # 動画
#mappingVideo= "http://{IP Address}:8090/?action=stream" # MJPG-Streamer
outputVideo= "editV07.mp4"

# --- 抜粋 --- #

例)ストリーミングからマーカーを検出し画像を描画した場合のサンプル

例)ストリーミングからマーカーを検出し動画(MP4)を描画した場合のサンプル

参考:ストリーミングサーバーの構築

MJPG-Streamerのインストールはこちらを参考にしました。
https://qiita.com/suo-takefumi/items/2ae5527869dc13d038a9

まとめ

OpenCVの使い方を調べたのでその情報をまとめました。
OpenGLだと3Dオブジェクトも扱えるらしいので、そっちも調べようと思います。