はじめに
AruCoというARマーカーのライブラリがあるが、日本語の記事はどれもPython+OpenCVで単純なマーカーの検出を行うか、キャリブレーション処理の方法くらいしか記事がなかった。今回はマーカーの姿勢推定の精度向上を図るためダイヤモンドマーカーを使用するに至ったが、ダイヤモンドマーカーに関する日本語の記事がほとんどなかったため、備忘録も兼ねてダイヤモンドマーカーがどんなものなのかからダイヤモンドマーカーの検出までを書いていく。
環境
使用した環境は以下の通りになる
- Windows 10 Home
- OpenCV 4.1.1 (ソースからビルドする、opencv_contribもビルドすること)
- Visual Studio 2019
ダイヤモンドマーカーとは
3x3のチェスボード + ArUcoマーカー4つで作られるマーカーのこと、上記画像で1つのマーカーとして扱う。特徴として以下が挙げられている。
- 4つのマーカーIDを使用するため、より多くのマーカーを単一の辞書から作成できる(100個の辞書なら100^4個)
- チェスボードを使用しているため正確な姿勢推定が行える
マーカーの作成
マーカーを作成する関数が<opencv2/aruco/charuco.hpp>
内にあるため、それを使用する。
Python環境ではpip install opencv-python
とpip install opencv-contrib-python
でArUcoが使えるようになるが、その場合は以下のdrawCharucoDiamond
が使用できなかった。(ソースからビルドしたものを使えばできるかもしれないが未確認)
また、OpenCVForUnityでも実行ができなかったので注意。
cv::aruco::drawCharucoDiamond(dictionary, cv::Vec4i(45,68,28,74), 200, 120, markerImage);
// 引数
// dictionary マーカーの辞書
// ids ダイヤモンドマーカーに使用する4つのマーカーID
// squareLength ピクセル単位のチェスボードの辺の長さ
// markerLength ピクセル単位のArUcoマーカーの長さ
// img 出力画像、画像サイズは3*squareLength + 2*marginSizeになる
// marginSize 出力画像におけるピクセル単位のマージンのサイズ
// borderBits マーカーの境界線の幅
マーカーの検出
マーカーの検出は一度通常のArUcoマーカーを検出してから、ダイヤモンドマーカーかを判定する検出を行う。
// 通常のArUcoマーカー検出
cv::aruco::detectMarkers(inputImage, dictionary, markerCorners, markerIds);
// 検出されたマーカーのコーナーとIDを使ってダイヤモンドマーカーの検出を行う
cv::aruco::detectCharucoDiamond(inputImage, markerCorners, markerIds, squareLength / markerLength, diamondCorners, diamondIds);
// 引数
// image 入力画像
// markerCorners detectMarkersで取得したCorners
// markerIds detectMarkersで取得したIds
// squareMarkerLengthRate マーカ―サイズとチェスボードの辺の長さの比率、squareLength / markerLengthで計算できる
// diamondCorners Cornersの出力
// diamondIds Idsの出力、1つのダイヤモンドマーカーにつき4つのIdが出力される
// cameraMatrix カメラ行列
// distCoeffs 歪み係数