Skip to content

[Unity]OpenCVSharpでArUcoを用いてARマーカ検出を行う

OpenCVSharpはOpenCVをC#で利用するためのラッパーです.なので,OpenCVにある機能はだいたい使えます.ただマイナーなのか意外と情報が少ないのが難点です. ArUcoとは画像や映像の中からARマーカの検出・位置推定ができるライブラリです. 今回はこのライブラリをC#(Unity)で使用する方法を紹介します

開発環境

  • Unity 2018.2.6f1
    • Scripting Runtime Version* .NET 4.x.Equivalent
      • .NET 3.5でも動くはず推奨です
    • Api Compatibility Level* .NET Standard 2.0
  • OpenCVSharp3 4.0.0
  • Windows10 Home (64bit)

準備

  • このサイトを参考にしてArUco用のマーカを用意してください
    • http://pongsuke.hatenadiary.jp/entry/2017/06/09/122312
    • 僕は4X4_50で0~4番を作成し,印刷しました

マーカ検出

  • CvAruco.DetectMarkers
    • この1行だけで,フレーム内から指定したARマーカ辞書と一致するマーカを検出します.
  • CvAruco.DrawDetectedMarkers
    • この行で,検出されたマーカのIDと座標,輪郭の描画を行います.ちゃんと検出されているかを視覚的に確認するメソッドです.
  • ソースコード
    • 以下のプログラムをUnity上の適当なオブジェクトにアタッチしてください.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OpenCvSharp;
using OpenCvSharp.Aruco;

public class webcam : MonoBehaviour {

    private int source = 0; //カメラのインデックス

    private VideoCapture cam;
    public Mat cam_frame;

    /* ArUcoの設定 */
    //ARマーカ辞書の設定
    private const PredefinedDictionaryName dictName = PredefinedDictionaryName.Dict4X4_50;
    private Dictionary ar_dict;
    //検出アルゴリズムの設定
    private DetectorParameters detect_param;

    void Start () {
        cam = new VideoCapture(source);
        cam.Set(CaptureProperty.ConvertRgb,3);
        cam_frame = new Mat();

        ar_dict = CvAruco.GetPredefinedDictionary(dictName);
        detect_param = DetectorParameters.Create();
    }
    
    void Update () {

        Point2f[][] maker_corners;  //ARマーカのカドの座標
        int[] maker_ids;            //検出されたARマーカのID
        Point2f[][] reject_points;

        cam.Read(cam_frame);//フレームの更新
        
        //ARマーカの検出
        CvAruco.DetectMarkers(cam_frame, ar_dict, out maker_corners, out maker_ids, detect_param, out reject_points);
        
        if(maker_ids.Length > 0){
            //検出されたマーカ情報の描画
            CvAruco.DrawDetectedMarkers(cam_frame, maker_corners, maker_ids, new Scalar(0, 255, 0));
        }
    }
}

描画

このままでは内部的に値を取得しただけなので,視覚的にわかりやすいようにcam_frame(カメラの映像)をテクスチャとしてオブジェクトに反映させます.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class camtexture_cam : MonoBehaviour {
    
    public webcam _webcam;
    private Texture2D cam_Texture;
    
    void Start () {
        cam_Texture = new Texture2D(
            640,    //カメラのwidth
            480,    //カメラのheight
            TextureFormat.YUY2, //フォーマットを指定
            false               //ミニマップ設定
        );
        this.GetComponent<Rendere>().material.mainTexture = cam_Texture;
    }
    
    // Update is called once per frame
    void Update () {
        cam_Texture.LoadImage(_webcam.cam_frame.ImEncode());
    }
}
 

ノートパソコンのインカメで撮影したので,少し不自然な角度ですがしっかりマーカの検出ができていることが確認できます.  

One thought on “[Unity]OpenCVSharpでArUcoを用いてARマーカ検出を行う

  1. ArUcoマーカーの検出は理解できました。この上にオブジェクトを置く場合はどのようなソースコードになるか教えていただけると幸いです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です