凹みTips

C++、JavaScript、Unity、ガジェット等の Tips について雑多に書いています。

軽量な AR ライブラリの ArUco を Mac で使ってみた

はじめに

ArUcoBSD ライセンスで配布されている OpenCV をベースにした軽量な AR ライブラリです。

以下の様な 2 次元マーカを 1024 個まで同時に認識可能です。

f:id:hecomi:20140405221655j:plain

例としては Oculus Rift 用のステレオカメラである Ovrvision の SDK が利用しています。

2 次元状にマーカを配置したボードを利用してロバスト性をあげる仕組みも入っています。

また他言語のバインディングや実装もあります。

本エントリでは、この AruCo を Mac で利用する方法について簡単にまとめてみました。

ビルド

ArUco のページの Download のところから「Download ArUco」および「Download ArUco Test Data」を開き、sorceforge からそれぞれ「aruco-1.2.5.tgz」と「aruco-1.2.2-testdata.zip」を落としてきて解凍します。

CMake を使ってビルドするのですが、Mac の標準の clang は OpenMP に対応していないのでそのままビルドするとエラーが出ます。

$ cmake .
...()...
$ make
Scanning dependencies of target aruco
[  3%] Building CXX object src/CMakeFiles/aruco.dir/ar_omp.cpp.o
[  7%] Building CXX object src/CMakeFiles/aruco.dir/arucofidmarkers.cpp.o
[ 11%] Building CXX object src/CMakeFiles/aruco.dir/board.cpp.o
[ 15%] Building CXX object src/CMakeFiles/aruco.dir/boarddetector.cpp.o
[ 19%] Building CXX object src/CMakeFiles/aruco.dir/cameraparameters.cpp.o
[ 23%] Building CXX object src/CMakeFiles/aruco.dir/chromaticmask.cpp.o
[ 26%] Building CXX object src/CMakeFiles/aruco.dir/cvdrawingutils.cpp.o
[ 30%] Building CXX object src/CMakeFiles/aruco.dir/highlyreliablemarkers.cpp.o
[ 34%] Building CXX object src/CMakeFiles/aruco.dir/marker.cpp.o
[ 38%] Building CXX object src/CMakeFiles/aruco.dir/markerdetector.cpp.o
In file included from /Users/hecomi/Downloads/aruco-1.2.5/src/markerdetector.cpp:36:
/Users/hecomi/Downloads/aruco-1.2.5/src/./ar_omp.h:31:10: fatal error: 'omp.h' file not found
#include <omp.h>
         ^
1 error generated.
...()...

CMakeList.txt を編集して OpenMP をオフにします。

CMakeList.txt:78-81
ELSE()
    # 以下の 2 行をコメントアウト
    # add_definitions(-DUSE_OMP -fopenmp)
    # set (REQUIRED_LIBRARIES ${REQUIRED_LIBRARIES} -lgomp)
ENDIF()

これでビルドが通るようになります。

$ rm CMakeCache.txt
$ cmake .
$ make

ビルドすると src の中に libaruco.1.2.5.dylib があります。utils にはマーカを生成する aruco_create_marker など様々なツールが入っています。例えば、aruco_create_marker は、

$ ./aruco_create_marker 123 123.png 256

で 123 番の 256px のマーカ画像が生成されます。

サンプルを動かす

では、試しにサンプルコードを動かしてみます。まず分かりやすいように作業ディレクトリにライブラリとヘッダをコピーしておきます。

$ cd YOUR_WORK_DIR
$ mkdir include lib
$ cp ARUCO_INSTALL_DIR/src/*.h include/.
$ cp ARUCO_INSTALL_DIR/src/libaruco1.2.5.dylib lib/.

また、「aruco-1.2.2-testdata.zip」に入っているカメラパラメタの YAML と、サンプルの画像もコピーしておきます。

$ cp ARUCO_TEST_DATA/board/intrinsics.yml .
$ cp ARUCO_TEST_DATA/board/image-test.png .

そして次のようなコードを書きます。

aruco.cpp

#include <opencv2/opencv.hpp>
#include <aruco.h>

int main(int argc, char* argv[])
{
    // マーカを含む画像
    cv::Mat inputImage = cv::imread("./image-test.png");

    // カメラパラメタのロード
    aruco::CameraParameters params;
    params.readFromXMLFile("./intrinsics.yml");
    params.resize(inputImage.size());

    // マーカを認識する
    aruco::MarkerDetector detector;
    std::vector<aruco::Marker> markers;
    const float markerSize = 0.04f;
    detector.detect(inputImage, markers, params, markerSize);

    // 結果を書き出す
    auto outputImage = inputImage.clone();
    for (auto&& marker : markers) {
        std::cout << marker << std::endl;
        marker.draw(outputImage, cv::Scalar(0, 0, 255), 2);
        aruco::CvDrawingUtils::draw3dCube(outputImage, marker, params);
    }

    // 結果を書き出す
    cv::namedWindow("input");
    cv::imshow("input", inputImage);
    cv::namedWindow("output");
    cv::imshow("output", outputImage);
    cv::waitKey(0);

    return 0;
}

そしてビルドして実行してみます。

$ clang++ main.cpp -Llib -Iinclude -laruco.1.2.5 -lopencv_core -lopencv_highgui -std=c++11 -o test
$ ./test

64=(292.438,281.347) (291.78,218.483) (344.908,218.539) (345.1,279.01) Txyz=0.0110084 0.00691255 0.421726 Rxyz=-3.05481 0.0152297 -0.695623 
76=(460.639,335.036) (461.067,283.905) (495.496,281.239) (494.672,329.868) Txyz=0.144801 0.054702 0.496637 Rxyz=-3.06084 0.0171299 -0.74177 
...(以下認識したマーカの結果が出力される)...

f:id:hecomi:20150617191135p:plain

無事出力されました。

おわりに

基本的なマーカの情報は勉強要らずで簡単に使えてとても便利です。ボードの認識や 1.2.5 で追加された Chromatic Mask などは追々試してみます。