2021年10月22日

【ARFoundation】撮影した写真をそのままARマーカーに設定する

目次

  1. はじめに
  2. プロジェクトの準備
  3. コンポーネントを追加する
  4. コードを書く(撮影部分)
  5. コードを書く(マーカーとして登録)

はじめに

この記事では、Unityで使うことのできるフレームワーク、ARFoundationを使って撮影した画像をマーカーにする方法を書いていきます!

ARFoundationとは?

unityで提供されているフレームワークの一つで、IOSとAndroidの区別をあまり意識することなく、簡単にAR体験をすることのできるものです。このフレームワーク一つで画像(マーカー)の認識、顔認識、平面認識などさまざまなARプロジェクトを構築することができます。

プロジェクトの準備

ProjectにARFoundationを入れる

環境

  • Unity 2020.3.11f
  • ARFoundation 4.1.7
  • Google Pixel 3a XL(Androidバージョン 11)

まずはUnityの3Dプロジェクトを立ち上げ、Window> PackageManagerから、ARFoundationと(今回使用するのはAndroid端末なので)ARCoreXR PluginをInstallしましょう。
スクリーンショット 2021-10-12 10.09.46.png (268.4 kB)

ビルド設定

次に、FIle>BuildSettingsより、PlatformをAndroidにします。プラットフォームの切り替えが終わったらPlayerSettings>Playerに移動し、Androidの設定項目を下記のように変更します。
– RenderlingのColorSpaceをGammaに変更
スクリーンショット 2021-10-20 12.07.53.png (28.7 kB)

  • IdentifivationのMinimum APILevelをAndroid7.0以上に変更
  • ConfigrationのScripting BackendをIL2CPPに変更
  • ConfigrationのTarget ArchitecturesのARM64にチェック
    スクリーンショット 2021-10-20 12.07.23.png (76.6 kB)

最後に、PlayerSettings>XR Plug-in Managementに移動し、ARCoreにチェックを入れます。
スクリーンショット 2021-10-20 12.08.25.png (56.9 kB)

これで基本的なプロジェクト設定は完了です。

コンポーネントを追加する

AR表示のために必要なオブジェクトを配置

Unity内のヒエラルキー内で右クリック>XRより、AR Session OriginとAR Sessionを追加します。
スクリーンショット 2021-10-20 12.09.36.png (85.4 kB)
追加したAR Session Originを選択し、Add ComprnentからAR Tracked Image Managerを追加します。
また、Main Cameraは削除しましょう。

ここまででARを表示するためのオブジェクトは配置できました。

ARで表示するオブジェクトの設定

ARでマーカーを読み込んだ際に表示するオブジェクトは、先ほど追加したAR Tracked Image Managerに設定します。
AR Tracked Image Managerには3つの設定箇所があります。
スクリーンショット 2021-10-18 17.36.34.png (40.9 kB)
Serialized Libralyは通常であれば参照するマーカーの設定をする「ReferenceImageLibrary」を設定しますが、今回は空欄のままで構いません。
Max Number Of Moving Imagesはトラッキングする画像の数を設定しますが、今回は1にします。
最後にTracked Image Prefabには実際に表示するプレハブを設定します。今回は3D Object内に用意されているCubeをプレハブ化し設定しました。
ただし、そのままでは大きすぎるのでScaleは(0.1, 0.1, 0.1)にしています。

UIの配置

写真を撮影するためのボタンと、撮影した写真を確認するビューを配置します。
ヒエラルキービューで右クリック>UIより、Buttonと、RawImageを配置します。
ボタンの大きさや配置はお好みですが、今回は下記のように設定しています。
スクリーンショット 2021-10-18 17.44.59.png (87.5 kB)

RawImageも同様ですが、撮影する画像の比率と合わせた方が、画像の確認がしやすいです。
今回は撮影を800*800の大きさで行うことにしましたので設定は下記のようにしました。
スクリーンショット 2021-10-18 17.47.09.png (85.3 kB)

配置の確認

これでオブジェクトの設定は概ね完了です。最終的な配置は下記のようになります。
スクリーンショット 2021-10-12 10.52.10.png (191.5 kB)

コードを書く(撮影部分)

それではいよいよコーディングをしていきましょう!!
プロジェクトビューで右クリック>Create>C# Scriptからスクリプトを作成します。名前は任意ですが、この例では「TakePhoto」にします。
作成したスクリプトをAR Session Originに設定します。

今回、撮影の流れは下記のようになります。
1. ボタンなど、UIの非表示
2. 撮影
3. UIの再表示
4. 撮影した画像をRawImageとマーカーに設定

UIの非表示

今回UIとして配置しているのはButtonとRawImageの2つです。
あらかじめ参照させておき、ボタンを押した時にSetActiveをfalseにすることで非表示にします。
publicまたは[SerializeField] private で宣言することで、unity上で設定することができます。

また、ここで定義する InActiveateUI()はボタンから呼び出すものになるため、publicで定義します。

public class TakePhoto : MonoBehaviour
{
    [SerializeField] private GameObject button;
    [SerializeField] private GameObject rawImage;

    public void InActiveateUI()
    {
        button.SetActive(false);
        rawImage.SetActive(false);
    }
}

ButtonとRawImageそれぞれをunity上で設定します。
スクリーンショット 2021-10-18 18.35.27.png (53.5 kB)

撮影

次に撮影部分を実装します。
先ほどUIを非表示にしましたが、そのまま撮影に入ると、非表示になりきれずに撮影される場合があります。
そのため、コルーチンのWaitForEndOfFrame()を使用して1フレーム分待機することで非表示になるのを待ちます。

POINT!!

撮影はUIが非表示になるのを待ってから

その後スクリーンショットを撮影します。
unityにはCaptureScreenshotというスクリーンショットのためのメソッドが用意されているのですが、今回は解像度を細かく設定したいのと、撮影した画像を保存するわけではないため別の方法で撮影しています。

撮影する画像は画面全体ではなく、800*800の大きさにしました。画面全体だとマーカーとしての判定がシビアになってしまい、スムーズな判定ができなくなってしまったためです。画面に表示されているものをTexture2Dに変換する形にしました。
ここまでの記述は下記のようになります。

private Texture2D screenShot;
public class TakePhoto : MonoBehaviour
{
    public void InActiveateUI()
    {
        ~~中略~~
        StartCoroutine(ScreenShot());
    }
    private IEnumerator ScreenShot()
    {
        //UIが消えるまで待つ
        yield return new WaitForEndOfFrame();

        //スクリーンショット撮影
        int width = 800;
        int height = 800;
        screenShot = new Texture2D(width, height, TextureFormat.RGB24, false);
        screenShot.ReadPixels(new Rect(0, 0, width, height), 0, 0);
        screenShot.Apply();
    }
}

UIの再表示

再表示の際はフレームを待つ必要はなく、単純にSetActiveをtrueにすれば良いです。

private IEnumerator ScreenShot()
{
    ~~中略~~
    button.SetActive(false);
    rawImage.SetActive(false);
}

撮影した画像をRawImageとマーカーに設定

撮影した画像をRawImageに追加するのは簡単で、RawImageを取得し、その中のテクスチャを置き換えれば良いだけです。
この記述はScreenShot()の末尾に追加しておきましょう。

private IEnumerator ScreenShot()
{
    ~~中略~~
    //画像をRawImageに設定
    RawImage imageTarget = rawImage.GetComponent<Rawimage>();
    imageTarget.texture = screenShot;
}

さて、いよいよマーカーに設定してみましょう!
今回はプロジェクト内でマーカーを登録するための「ReferenceImageLibrary」を作成していないため、ここで作成していく必要があります。CreateRuntimeLibrary()というメソッドが用意されていますので、こちらを使います。
作成したライブラリーにスクリーンショットを登録し、トラッキングを開始する記述を書けばスクリプトは完成です!
ここで使用するScheduleAddImageWithValidationJobメソッドの引数は(登録するマーカー, 登録するマーカーの名前, マーカーとしての大きさ)になります。

private IEnumerator ScreenShot()
{
    ~~中略~~
    SetTrakedImage();
}
private void SetTrakedImage()
{
    //画像を登録するためのライブラリーを作成する
    aRTrackedImageManager.referenceLibrary = aRTrackedImageManager.CreateRuntimeLibrary();

    //トラッキングする画像として撮影したスクリーンショットを追加する
    if (aRTrackedImageManager.referenceLibrary is MutableRuntimeReferenceImageLibrary mutableLibrary)
    {
        mutableLibrary.ScheduleAddImageWithValidationJob(screenShot, "my new image", 0.5f);    // 0.5f = 50cm
    }
    //トラッキングをオンにする
    aRTrackedImageManager.enabled = true;
}

お疲れさまでした!と言いたいところですが、最後に一つ工程が残っています。
ボタンを押した際に呼び出すメソッドを設定します!unityに戻り、ButtonのOn Clickで+ボタンを押しInActiveateUI()を選択します。
スクリーンショット 2021-10-19 16.33.00.png (31.5 kB)

これで実装はおしまいです!

POINT!!

Buttonの設定を忘れずに!

最後にスクリプトの全体を載せておきます。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR.ARFoundation;
using UnityEngine.XR.ARSubsystems;

public class TakePhoto : MonoBehaviour
{
    [SerializeField] private GameObject button;
    [SerializeField] private GameObject rawImage;
    [SerializeField] private ARTrackedImageManager aRTrackedImageManager;
    private Texture2D screenShot;

    public void InActiveateUI()
    {
        button.SetActive(false);
        rawImage.SetActive(false);

        StartCoroutine(ScreenShot());
    }

    private IEnumerator ScreenShot()
    {
        //UIが消えるまで待つ
        yield return new WaitForEndOfFrame();

        //スクリーンショット撮影
        int width = 800;
        int height = 800;
        screenShot = new Texture2D(width, height, TextureFormat.RGB24, false);
        screenShot.ReadPixels(new Rect(0, 0, width, height), 0, 0);
        screenShot.Apply();

        //UIを元に戻す
        button.SetActive(true);
        rawImage.SetActive(true);

        SetTrakedImage();
    }

    private void SetTrakedImage()
    {
        //画像をRawImageに設定
        RawImage imageTarget = rawImage.GetComponent<Rawimage>();
        imageTarget.texture = screenShot;

        //画像を登録するためのライブラリーを作成する
        aRTrackedImageManager.referenceLibrary = aRTrackedImageManager.CreateRuntimeLibrary();

        //トラッキングする画像として撮影したスクリーンショットを追加する
        if (aRTrackedImageManager.referenceLibrary is MutableRuntimeReferenceImageLibrary mutableLibrary)
        {
            mutableLibrary.ScheduleAddImageWithValidationJob(
                screenShot,
                "my new image",
                0.5f); /* 50cm */
        }
        //トラッキングをオンにする
        aRTrackedImageManager.enabled = true;
    }
}

こちらをビルドして実行するとこんな感じになります!
撮影した直後に、風景がマーカーとして登録され、cubeが登場するのがみれると思います。
背景が均一であれば、色々なものに追従させることもできそうです!

さいごに

今回はARFoundationを使って、撮影した写真をマーカーに設定する方法をご紹介しました!
少しでもARって面白い、やってみたい!と感じていたければ幸いです。
最後までご覧いただき、ありがとうございました!

NativeAR/VRのお仕事に関するご相談

Bageleeの運営会社、palanではNativeAR/VRに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。

無料相談フォームへ

0

0

AUTHOR

nagao

SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

アプリでもっと便利に!気になる記事をチェック!

記事のお気に入り登録やランキングが表示される昨日に対応!毎日の情報収集や調べ物にもっと身近なメディアになりました。

簡単に自分で作れるWebAR

「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。

palanARへ
palanar

palanはWebARの開発を
行っています

弊社では企画からサービスの公開終了まで一緒に関わらせていただきます。 企画からシステム開発、3DCG、デザインまで一貫して承ります。

webar_waterpark

palanでは一緒に働く仲間を募集しています

正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。

話を聞いてみたい

運営メンバー

eishis

Eishi Saito 総務

SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。

sasakki デザイナー

アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

yamakawa

やまかわたかし デザイナー

フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。

Sayaka Osanai デザイナー

Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた

はらた エンジニア

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

kobori

こぼり ともろう エンジニア

サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

sasai

ささい エンジニア

フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

damien

Damien

WebAR/VRを中心に企画・マークアップ・開発をやっています。森に住んでいます。

ゲスト bagelee

ゲスト bagelee

かっきー

かっきー

まりな

まりな

suzuki

suzuki

taro

taro

xR界隈のビズをやっています。新しいガジェットとか使うのが好きです。あとお寿司は玉子のお寿司が好きです。

miyagi

ogawa

ogawa

雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。

いわもと

いわもと

kobari

taishi kobari

フロントエンドの開発を主に担当してます。Blitz.js好きです。

shogokubota

kubota shogo

サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!

nishi tomoya

aihara

aihara

グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。

nagao

SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

kainuma

Kainuma

サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

sugimoto

sugimoto

CONTACT PAGE TOP