♣️

Mind-ARとThree.jsで画像認識

2022/12/28に公開

概要

こんにちは、株式会社palanのxR事業部でWebAR/VRの開発をしているdamiと申します。
年の瀬ですね。いま口内炎が同時に3つできています。

本記事では、WebAR開発ライブラリ「Mind-AR」とThree.jsを使って画像認識(Image Tracking)コンテンツをつくる方法についてまとめます。

対象とする読者

  • Three.jsを使ったことがある方

Mind-ARの基本情報や、より簡単なA-Frameと併用した開発方法について知りたい方は、以前書いたこちらの記事をご参照ください。
https://zenn.dev/dami/articles/a1fdbb34e0be93

1. 画像マーカーの用意

まずは認識したいマーカーを用意します。
Mind-ARでは好きな画像を専用マーカーデータに変換できるコンパイラがありますので、こちらを利用してマーカーデータ(.mind拡張子)を用意します。
コンパイル方法はこちらで詳しく紹介していますので割愛。

本記事ではniji journeyで生成したイラストをマーカーにしてみます。

2. ライブラリのインストール

ライブラリのインストールを行いましょう。

CDNを利用するの場合

index.html
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
  "imports": {
    "three": "https://unpkg.com/three@0.147.0/build/three.module.js",
    "three/addons/": "https://unpkg.com/three@0.147.0/examples/jsm/",
    "mindar-image-three":"https://cdn.jsdelivr.net/npm/mind-ar@1.2.0/dist/mindar-image-three.prod.js"
  }
}
</script>

npm installするの場合

> npm i mind-ar
> npm i three

3. 基本のコード

基本のコードはこのようなかたちです。

index.html
<div id="control">
  <button id="startButton">Start</button>
  <button id="stopButton">Stop</button>
</div>
<div id="container"></div>
style.css
body {
  margin: 0;
}
#container {
  width: 100vw;
  height: 100vh;
  position: relative;
  overflow: hidden;
}
#control {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2;
}
script.ts
import * as THREE from "three";
import { MindARThree } from "mind-ar/dist/mindar-image-three.prod.js";

let mindarThree;
let renderAnimationId = null;
const container = document.getElementById("container");

mindarThree = new MindARThree({
  container: container,
  // mindマーカーのパス
  imageTargetSrc: "./marker.mind",
});

const { renderer, scene, camera } = mindarThree;
const anchor = mindarThree.addAnchor(0);
// マーカー起点に表示させるオブジェクトの用意
const geometry = new THREE.PlaneGeometry(1.5, 1.5);
const material = new THREE.MeshBasicMaterial({
  color: 0x00ffff,
  transparent: true,
  opacity: 0.5,
});
const plane = new THREE.Mesh(geometry, material);
// マーカー位置を追従するanchor.groupにオブジェクトを入れる
anchor.group.add(plane);

const update = () => {
  renderer.render(scene, camera);
  renderAnimationId = requestAnimationFrame(update);
};

const start = async () => {
  await mindarThree.start();
  update();
};

// スタートボタン・ストップボタンで認識&描画を操作するための処理
const startButton = document.getElementById("startButton");
const stopButton = document.getElementById("stopButton");
startButton.addEventListener("click", () => {
  start();
});
stopButton.addEventListener("click", () => {
  mindarThree.stop();
  cancelAnimationFrame(renderAnimationId);
});

「start」のボタン押すと画像認識が開始するようになりました。

3-a. マルチマーカー

マルチマーカー(複数のマーカーファイルの認識し分け)の際は、以下のようにanchorをマーカー数と合わせて追加することで実現できます。

script.ts
// マーカー数のanchorを追加
const anchor00 = mindarThree.addAnchor(0);
const anchor01 = mindarThree.addAnchor(1);

const geometry = new THREE.PlaneGeometry(1.5, 1.5);
const material00 = new THREE.MeshBasicMaterial({
  color: 0x00ffff,
  transparent: true,
  opacity: 0.5,
});
const material01 = new THREE.MeshBasicMaterial({
  color: 0xff00ff,
  transparent: true,
  opacity: 0.5,
});
const plane00 = new THREE.Mesh(geometry, material00);
const plane01 = new THREE.Mesh(geometry, material01);

// それぞれのanchor.groupごとに、配置したいオブジェクトを入れる
anchor00.group.add(plane00);
anchor01.group.add(plane01);

0, 1...といったindexがどのマーカー画像に紐づくかは、コンパイラにアップロードした順になります。

3-b. マルチトラック

マルチトラック(複数マーカーの同時認識) の設定は、MindARThreeクラスのインスタンスを作成する際に引数として渡すことで指定ができます。

script.ts
mindarThree = new MindARThree({
  container: container,
  // maxTrack = 最大同時認識数
  maxTrack: 2,
  imageTargetSrc: "./multi-targets.mind",
});

3-c. イベント

マーカー発見のイベントは以下の方法で検知することができます。

anchor00.onTargetFound = () => {
  alert("target00 found");
};
anchor00.onTargetLost = () => {
  alert("target00 lost");
};

参考 - 公式ドキュメント

インストールまわり
https://hiukim.github.io/mind-ar-js-doc/installation/#threejs-installation

Three.js Image Tracking
https://hiukim.github.io/mind-ar-js-doc/more-examples/threejs-image/

Discussion