おもちゃラボ

Unityで遊びを作ってます

【AR Foundation】 光源推定をする

f:id:nn_hokuson:20201124151400j:plain

今回はAR Foundationで光源推定をする方法を紹介します。Directional Lightのデフォルト設定では現実の光源の強さや色合と異なるため、違和感がある映像になってしまいます。AR Foundationでは撮影された映像から光源の強さと色合いを推定できる光源推定機能が用意されているので、その使い方を紹介します。

AR Foundationの光源推定でできること

ARを周辺の環境となじませるためには、その環境に応じたライトの設定をする必要があります。そのため、AR Foundationには現実の光源のパラメータを推定する機能があります。光源推定で推定できる値は次のようなものがあります。

Ammbient Intensity 環境光の強さ
Ambient Color 環境光の色温度
Main Light Direction ライトの方向
Main Light Intensity ライトの強さ

ARKitでは上記のうち、ライトの方向と強さ(Main Light DirectionとMain Light Intensity)は推定できないことに注意してください。

f:id:nn_hokuson:20180925233222p:plain:w450

それでは、AR Foundationで得られる光源の推定値をUnityのライトに設定する方法を見ていきましょう。

Unityプロジェクトの作成と下準備

次にUnityでの作業に移ります。AR Foundationを使ったプロジェクトの作り方と、その準備についてはこちらの記事に詳しく説明しています。

nn-hokuson.hatenablog.com

ここでは、ヒエラルキーウインドウにAR SessionとAR Session Originオブジェクトを配置し終えたところからスタートします。

f:id:nn_hokuson:20201112202225p:plain:w550

光源推定を行う

ヒエラルキーウインドウで、AR Session Origin の子要素のAR Cameraを選択してください。

f:id:nn_hokuson:20201122104319p:plain:w250

AR CameraにアタッチされているAR Camera ManagerのLight Estimationの項目から「Ammbient Intensity」と「Ambient Color」を選択してください。

f:id:nn_hokuson:20201122104337p:plain:w250 f:id:nn_hokuson:20201122104349p:plain:w250

これでAR Foundationで環境光の色と強さを推定できるようになります。次に推定した値を実際のライトへ反映する必要があります。そのためのスクリプトを作成します。LightEstimateという名前でC#スクリプトを作成して、次のプログラムを入力してください。

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

public class LightEstimate : MonoBehaviour
{
    [SerializeField] ARCameraManager cameraManager;
    private Light light;

    void Start()
    {
        this.light = GetComponent<Light>();        
        cameraManager.frameReceived += OnCameraFrameReceived;
    }

    void OnCameraFrameReceived(ARCameraFrameEventArgs e)
    {
        Color color = Color.white;
        float intensity = 1.0f;

        if (e.lightEstimation.averageBrightness.HasValue)
        {
            intensity = e.lightEstimation.averageBrightness.Value;
            intensity *= 2.0f;
            if (intensity > 1) intensity = 1.0f;
        }
        if (e.lightEstimation.averageColorTemperature.HasValue)
        {
            color = Mathf.CorrelatedColorTemperatureToRGB(e.lightEstimation.averageColorTemperature.Value);
        }

        Color c = color * intensity;
        light.color = c;
        RenderSettings.ambientSkyColor = c;
    }

    private void OnDisable()
    {
        cameraManager.frameReceived -= OnCameraFrameReceived;
    }
}

光源のパラメータを推定した値はAR CameraManagerから送られてきます。 推定値を毎フレーム値を取得するため、frameReceivedイベントにOnCameraFrameReceivedメソッドを追加しています。

OnCameraFrameReceivedで、実際に光源推定した値をライトに反映する作業を行っています。ライトの推定値は引数であるARCameraFrameEventArgsのlightEstimation.averageBrightness.ValueとlightEstimation.averageColorTemperature.Valueに格納されています。推定した光源の色と強度をかけ合わせた値をDirectional Lightのcolorに設定しています。

また、ライトに反映すると同時にRenderSettings.ambientLightにも値を設定しています。これにより、環境から受ける光の強さと色も同時に設定しています。この設定はメニューのWindow/Rendering/LightingのEnvironment Lightから設定するパラメータに相当します。

f:id:nn_hokuson:20201122104531p:plain:w450

スクリプトをアタッチする

作成したLightEstimateスクリプトをDirectional Lightにドラッグ&ドロップしてアタッチしてください。

f:id:nn_hokuson:20201124144642p:plain:w650

次に今アタッチしたスクリプトのAR Camera Managerの欄に、AR Session Origin/ARCameraをドラッグ&ドロップしてください。

f:id:nn_hokuson:20201124144653p:plain:w650

実行結果

これでAR Tracked Object Managerの設定は終わりです。最後にAR Foundationの各種設定を次の記事を参考にして行い、実行してみてください。

nn-hokuson.hatenablog.com

ビルドして実行すると、ライトの色がモデルに反映されて、より自然なARになっていることが確認できます。

f:id:nn_hokuson:20201124151232g:plain:w500

まとめ

この記事では、AR Foundationを使って光源のパラメータを推定する方法を紹介しました。また、AR Foundationの基礎になっているARKitについては「swiftで作る ARKit超入門」がオススメです!こちらも、ぜひ参照ください。
booth.pm

【Raspberry Pi】ストリーミング配信した映像をOpenCVで受け取る

この記事ではRaspberry Piに接続したカメラの映像をストリーミング配信して、その映像をMacやPCで受け取る方法を紹介します。

f:id:nn_hokuson:20201116160445p:plain

Raspberry Piからのストリーミング映像はブラウザでも受け取れますが、ここではOpenCVで受け取る方法も合わせて紹介します。

Raspberry Piでストリーミング配信する

Raspberry Piに接続したカメラからストリーミング配信するにはmjpg-streamerを使用します。mjpg-streamerのインストール方法は次の記事のとおりです。

qiita.com

インストールのコマンドだけこちらにまとめておきます。

$ sudo apt-get install -y cmake libv4l-dev libjpeg-dev imagemagick
$ git clone https://github.com/jacksonliam/mjpg-streamer.git
$ cd mjpg-streamer/mjpg-streamer-experimental
$ sudo make; sudo make install

インストールができたら、次のコマンドでストリーミング配信を開始します。

sudo ./mjpg_streamer -i "./input_uvc.so -f 30 -r 320x240 -d /dev/video0 -y -n" -o "./output_http.so -w ./www -p 8080"

ストリーミング配信時に指定できる主なオプションは次のようになります。

オプション 意味
-d デバイス名
-r 解像度
-f フレームレート
-p ポート番号

ストリーミング配信動画を受けとる

ブラウザで動画を受け取る

まずは、Raspberry Piで配信したストリーミング映像がちゃんと表示されているか、ブラウザで確認してみましょう。ブラウザに

http://ラズパイのIPアドレス:8080/?action=stream

と入力してください。次のようにRaspberry Piに接続したカメラの映像が映っていればOKです。

f:id:nn_hokuson:20201116161057j:plain:w450

OpenCVで映像を受け取る

ストリーミングの映像が受け取れていることが確認できたら、次はOpenCVを使って映像を受け取ります。

OpenCVを使って映像を受け取るために、次のpythonプログラムを入力してください。

import cv2

url = "http://ラズパイのIPアドレス:8080/?action=stream"
video = cv2.VideoCapture(url)

while True:
    ret, frame = s_video.read()
    edges = cv2.Canny(frame,100,200)
    cv2.imshow("Test", edges)
    key = cv2.waitKey(1)
    if key == 27:
        break

OpenCVのVideoCaptureの引数にストリーミング配信元のURLを指定することで、動画を読み込むのと同じように映像をMat型で取得できます。上のサンプルでは取得した映像にCannyフィルタを掛けて出力しているので、次のような映像になりました。

f:id:nn_hokuson:20201116162150g:plain:w500
 

まとめ

Raspberry Piを使って映像を配信し、その映像をPC/MacからOpenCVで取得&表示する方法を紹介しました。

【AR Foundation】ぬいぐるみをマーカーにしてARを作る

ARKit2.0からは2次元の画像マーカーだけでなく、3次元の物体(例えばぬいぐるみとか、玩具とか)をマーカーに出来るようになりました。ただ、物体マーカーは2次元マーカーのように動かしてもARモデルは追従しないので注意が必要です。

f:id:nn_hokuson:20190625191641j:plain

物体をマーカーにする流れ

  1. マーカーにしたい物体を360度撮影して、物体のもつ特徴点データを抽出
  2. 作成した特徴点データをReferenceObjectLibraryに登録
  3. ReferenceObjectLibraryとARで表示したいモデルをARTrackedObjectManagerに登録

f:id:nn_hokuson:20201111131955p:plain:w650

このように書くと、多少複雑そうに見えますが、やっていることは画像マーカーを使用したときと同じことをしています。

nn-hokuson.hatenablog.com

一点違うのが❶の特徴点データを検出する部分です。ここはプログラマが手作業でやる必要があります。まずはその方法から見ていきましょう。

特徴点データを抽出する

3Dの特徴点データを取り出すには専用のアプリが用意されています。といっても、自分でビルドする必要があります(笑)

まずは次のサイトからARKit Scannerのプロジェクトをダウンロードしてください。

developer.apple.com

ダウンロードできたらビルドして、アプリを起動します。起動したらまずはマーカーにしたい物体を囲むように黄色い枠を広げます。枠のサイズはドラッグやピンチで変更できます。

f:id:nn_hokuson:20190616222022j:plain:w250

次に物体を360度(といっても底面はありませんが)から撮影します。うまく撮影できると、画面上のScanのパーセンテージが上昇し、ボックスの表面が黄色く変化します。

f:id:nn_hokuson:20190616222122j:plain:w250 f:id:nn_hokuson:20190616222416j:plain:w250

すべての面が撮影できたら「Share」ボタンを押して、特徴点データをPCに転送します(転送にはAirDropが便利!)。ファイル名は「Scan-xxxx.arobject」みたいになっていると思います。

f:id:nn_hokuson:20190616222529j:plain:w250

ここでは名前をyadon.arobjectに変更しておきました。

Unityプロジェクトの作成と下準備

次にUnityでの作業に移ります。AR Foundationを使ったプロジェクトの作り方と、その準備についてはこちらの記事に詳しく説明しています。

nn-hokuson.hatenablog.com

ここでは、ヒエラルキーウインドウにAR SessionとAR Session Originオブジェクトを配置し終えたところからスタートします。

f:id:nn_hokuson:20201112202225p:plain

特徴点データを読み込む

AR Foundationのセットアップができたら、先程転送した特徴点データをプロジェクトウィンドウにドラッグ&ドロップして追加しておきます。

f:id:nn_hokuson:20201112202235p:plain

ARマーカーのライブラリを作成する

AR Foundationで物体マーカーを使ったARを作る場合、まずはARマーカーのライブラリを作成します。ライブラリを作成するにはプロジェクトウィンドウで右クリック→Create→XR→Reference Object Libraryを選択してください。

f:id:nn_hokuson:20201112202305p:plain:w400

次に、作成したObject Libraryに先程の特徴点データを登録します。作成したReference Object Libraryを選択して、インスペクタから「Add Object」のボタンをクリックします。

f:id:nn_hokuson:20201112202257p:plain

新しくARの物体マーカーを登録する画面が表示されるので、先程の特徴点ファイルをドラッグ&ドロップします。また、Name欄には任意の名前を入力しておきます。

f:id:nn_hokuson:20201112202317p:plain

AR Tracked Object Managerの設定

ARマーカーライブラリの作成ができたので、次はこのライブラリをTracked Object Managerに登録します。Tracked Object Managerでは

  • ARマーカーライブラリの登録
  • ARマーカーが検出されたときに表示するARモデルの登録

を行います。

まずはヒエラルキーウインドウでAR Session Originを選択して、インスペクタのAdd Componentから「AR Tracked Object Manager」をアタッチします。

f:id:nn_hokuson:20201112202338p:plain

次にSerialized Libraryの欄に、作成したReferenceObjectLibraryをドラッグ&ドロップします。Tracked Object PrefabにARマーカーが検出されたときに表示するARモデルを設定します。

f:id:nn_hokuson:20201112202352p:plain

これでAR Tracked Object Managerの設定は終わりです。最後にAR Foundationの各種設定を次の記事を参考にして行い、実行してみてください。

nn-hokuson.hatenablog.com

物体ARマーカーの上に指定したARモデルが表示されれば成功です!

まとめ

この記事では、AR Foundationを使って物体をARマーカーにする方法を紹介しました。AR Foundationではマーカーを使ったARの他にも色々と面白い機能がありますので、こちらも今後、紹介していきたいと思います。