⑨[android][vuforia][ar]Vuforia(Image Target)を独自マーカーで複数検出させてみた。
第1回 VuforiaでARの初めの一歩
第2回 Vuforiaのサンプルコード(Image Targetのみ)を動かしてみた。
第3回 動画再生を板ポリ上で実行するサンプルコードを作ってみた。
第4回 Vuforiaで動画再生ARを実装してみた。
第5回 Vuforia11.4.4の公式サンプルコードを動かしてみた。
お薦めしません: 第6回 VuforiaのVuMarkを動かしてみた。
お薦めしません: 第7回 Vuforiaで独自VuMarkを作ってみた。←挑戦中 ←無理ゲーすぎた
第8回 Vuforia(Image Target)を独自マーカーで動かしてみた。
第9回 Vuforia(Image Target)を独自マーカーの複数検出させてみた。
左画像は青枠の中で3Dモデル表示 右画像は赤枠の中で動画再生が出来ている。
画像の同時検出もできている。
いったんここが区切りかな。一応動くので。
まだ データセット(xml/dat) をSDカードから読み込めるようにするとか、動画再生をストリーム再生に対応するとかやりたいことあるので、そこは気が向いたらやります。
ソースコードはここ↓
Abstruct
- 独自マーカーでImage Targetを複数検知させてみた。
- Vuforiaのバージョン 11.4.4。
※とはいえ、同時に両方検知とはいかないみたい。たぶん制限してんだろうな。
背景
第8回で言ってた通り、複数のARマーカーの検知をします。
ざっくり手順
- 2つ目のマーカを作成(Vuforiaサイトで)※1つ目は第8回で使ったマーカーです。
- githubからソースコード取得
- プロジェクトに組み込み → ビルド
準備
- android端末
- 開発用PC(Android Studioのインストールは済ませておく。)
- android端末をつないで、デバッグができる様にしておく。
- SDKと公式サンプルコードは今回一緒にgithubにコミットしたんで不要。
- Vuforiaのアカウント作成 前回の説明の準備1をやっておく。
- Vuforiaのライセンスキー取得 前回の説明の準備2をやって取得しておく。
手順1. 2つ目のマーカを作成(Vuforiaサイトで) → データセット(xml/dat)取得
-
2つ目のマーカーを準備
2つ目のマーカーは、下記画像を準備した。
MS Paintのクレヨンで適当に線を引いただけ。
※中身はいつでも差し替えれる様に枠だけ。 -
Vuforiaサイトで画像の追加登録 → データセット取得
このあたりは、第8回の手順2.3.と同じなのでそっち参照してください。
偶然の発見だけど、MS PaintのクレヨンはVuforiaの特徴認識アルゴリズムと相性がいいらしい。
びっくりするんだけど、認識精度星5つ!!
特徴点ビッシリ!!
手順2. githubからソースコード取得
下記コードをClone(or zipダウンロード)。
手順3. プロジェクトに組み込み → ビルド
-
Android Studioでプロジェクトを開く。
cloneしたAndKot-VuforiaVideoPlaybackを開く。
-
認証情報を設定した後、ビルドする。
Vuforiaのライセンス画面を開いて license Key をコピー。
↓
Android Studioで、"AppController.cpp"を開き、licenseKeyに、準備2でコピーしたライセンスを貼り付けます。
そして、ビルド。
※もし、この手順を飛ばしたら、アプリ起動時に下記エラーが発生します。
- 手順1でDLしたvuforiaのデータセット(.xml/.dat)をプロジェクトに組み込む
ゲットした bbb.zip は解凍するとbbb.xml / bbb.datの2ファイルが出来るので、その2つをAndroid プロジェクトに追加する。
app/
└── src/
└── main/
└── assets/
└── original/
├── bbb.dat
└── bbb.xml
ちなみにbbb.xmlの中身は、name="002_cleyon"とname="001_stones_jpg"の2つ登録されているのが分かる。
<?xml version="1.0" encoding="UTF-8"?>
<QCARConfig>
<Tracking>
<ImageTarget name="002_cleyon" size="0.100000 0.069915" />
<ImageTarget name="001_stones_jpg" size="0.100000 0.069915" />
</Tracking>
</QCARConfig>
- ソース修正。
createImageTargetList()を新規追加。
getImageTargetResult()に引数追加。
+ std::pair<std::unique_ptr<VuObservationList, decltype(&vuObservationListDestroy)>, int> createImageTargetList();
- bool getImageTargetResult(VuMatrix44F& projectionMatrix, VuMatrix44F& modelViewMatrix, VuMatrix44F& scaledModelViewMatrix, VuVector2F& markerSize);
+ bool getImageTargetResult(const VuObservation* observation, VuMatrix44F& projectionMatrix, VuMatrix44F& modelViewMatrix, VuMatrix44F& scaledModelViewMatrix, VuVector2F& markerSize, std::string& targetName);
新規追加のcreateImageTargetList()を実装。
+std::pair<std::unique_ptr<VuObservationList, decltype(&vuObservationListDestroy)>, int>
+AppController::createImageTargetList() {
+ VuObservationList* observationList = nullptr;
+ REQUIRE_SUCCESS(vuObservationListCreate(&observationList));
+
+ if (vuStateGetImageTargetObservations(mVuforiaState, observationList) != VU_SUCCESS) {
+ LOG("Error getting image target observations");
+ REQUIRE_SUCCESS(vuObservationListDestroy(observationList));
+ std::unique_ptr<VuObservationList, decltype(&vuObservationListDestroy)> _null_ptr_(nullptr, &vuObservationListDestroy);
+ return std::make_pair(std::move(_null_ptr_), 0);
+ }
+
+ int numObservations = 0;
+ REQUIRE_SUCCESS(vuObservationListGetSize(observationList, &numObservations));
+
+ std::unique_ptr<VuObservationList, decltype(&vuObservationListDestroy)> retptr(observationList, &vuObservationListDestroy);
+ return std::make_pair(std::move(retptr), numObservations);
+}
引数追加したgetImageTargetResult()に引数にセットする処理を追加。
あとは処理を簡潔にした。
bool
-AppController::getImageTargetResult(VuMatrix44F& projectionMatrix, VuMatrix44F& modelViewMatrix, VuMatrix44F& scaledModelViewMatrix, VuVector2F& markerSize)
+AppController::getImageTargetResult(const VuObservation* observation, VuMatrix44F& projectionMatrix, VuMatrix44F& modelViewMatrix, VuMatrix44F& scaledModelViewMatrix, VuVector2F& markerSize, std::string& targetName)
+ targetName = imageTargetInfo.name;
それら関数の呼び元を修正。
認識マーカ数だけloopする様に実装。だけど認識数は1つだけみたいだ。
+ auto [imageTargetList, CNT] = controller.createImageTargetList();
+ for (int idx = 0; idx < CNT; idx++) {
+ VuObservation* observation = nullptr;
+ if (vuObservationListGetElement(imageTargetList.get(), idx, &observation) != VU_SUCCESS)
+ continue;
+
+ assert(observation);
+ assert(vuObservationIsType(observation, VU_OBSERVATION_IMAGE_TARGET_TYPE) == VU_TRUE);
+ assert(vuObservationHasPoseInfo(observation) == VU_TRUE);
+
VuMatrix44F trackableProjection;
VuMatrix44F trackableModelView;
VuMatrix44F trackableModelViewScaled;
VuImageInfo modelTargetGuideViewImage;
VuBool guideViewImageHasChanged;
VuVector2F markerSize;
+ std::string tergetName;
- if (controller.getImageTargetResult(trackableProjection, trackableModelView, trackableModelViewScaled, markerSize))
+ if (controller.getImageTargetResult(observation, trackableProjection, trackableModelView, trackableModelViewScaled, markerSize, tergetName))
{
+ if(tergetName == "001_stones_jpg")
gWrapperData.renderer.renderVideoPlayback(trackableProjection, trackableModelView, trackableModelViewScaled, markerSize);
+ else if(tergetName == "002_cleyon")
gWrapperData.renderer.renderImageTarget(trackableProjection, trackableModelView, trackableModelViewScaled);
}
}
+ imageTargetList.reset();
で、実行。
出来た!!
25.09.24 更新 同時検出、出来た!!
マーカーの同時検出、できないと思ってたら出来た!!
設定関数があってそれを呼出す必要があった。実行関数は下記。
for(int lpct = 0; lpct < 2; lpct++) {
auto imageTargetConfig = vuImageTargetConfigDefault();
imageTargetConfig.databasePath = "orignal/image.xml";
if(lpct == 0)
imageTargetConfig.targetName = "001_stones_jpg";
else
imageTargetConfig.targetName = "002_cleyon";
- imageTargetConfig.activate = VU_TRUE;
+ imageTargetConfig.activate = VU_FALSE;
VuObserver* observer = nullptr;
VuImageTargetCreationError imageTargetCreationError;
if (vuEngineCreateImageTargetObserver(mEngine, &observer, &imageTargetConfig, &imageTargetCreationError) != VU_SUCCESS)
{
LOG("Error creating image target observer: 0x%02x", imageTargetCreationError);
mErrorMessageCallback("Error creating image target observer");
return false;
}
+ /* 同時認識数の設定*/
+ REQUIRE_SUCCESS(vuEngineSetMaximumSimultaneousTrackedImages(mEngine, 5));
+
+ /* Observerをアクティベート */
+ vuObserverActivate(observer);
+
mObjectObservers.push_back(observer);
}
画像の同時検出もできている。
無事同時検出も出来た!!
Discussion