Unity+OpenCvSharp3でWebカメラの映像を表示する
続きです。
お疲れ様です。 前回は画像を適当に保存するところまでしかやってないので、それではゲームに使えないだろうと表示を実装していきます。
結論から
まず、VideoCapture
クラスから取得できる画像データはMat
クラスのインスタンスとして変数に保存されます。
Mat
のメソッドとしてImEncode
というものありますが、これを用いpng画像のバイトデータを生成します。
これを、UnityのLoadImage
関数に渡すことでTextureに読み込むことができます。
さて、仕組みは以上です。
Mat -> png -> Texture2Dという風に変換するわけですね。
実装
usingディレクティブ
using UnityEngine; // uGUIのRawImageに読み込む場合 //using UnityEngine.UI; using OpenCvSharp;
フィールド宣言
[SerializeField] private int m_WebCamIndex = 0; private Texture2D m_Texture; private VideoCapture m_Video; private Mat m_Frame;
Startメソッド
private void Start() { // m_WebCamIndexによって指定されたウェブカメラを初期化 m_Video = new VideoCapture(m_WebCamIndex); // Texture2Dをウェブカメラのサイズ、フォーマットで初期化 m_Texture = new Texture2D( m_Video.FrameWidth, // ウェブカメラのwidth m_Video.FrameHeight, // ウェブカメラのheight TextureFormat.RGB24, // フォーマットを指定 false // ミップマップ設定(よくわかっていない) ); // テクスチャを適用したいオブジェクトにスクリプトを登録する // 以下どちらか // 1. スクリプトをuGUIのRawImageに登録している場合 GetComponent<RawImage>().texture = m_Texture; // 2. スクリプトをオブジェクトに登録している場合 GetComponent<Renderer>().material.mainTexture = m_Texture; }
Updateメソッド
private void Update { // ウェブカメラから画像読み込み m_Video.Read(m_Frame); // MatオブジェクトをPNGデータに変換、読み込み m_Texture.LoadImage(m_Frame.ImEncode()); }
OnDestroyメソッド
private void OnDestroy() { // カメラを閉じる処理を書かないと起動し続ける // .NETのバージョンをイジってないと動かないかもしれません m_Video?.Dispose(); m_Video = null; }
以上です。
Unityに慣れている人には特に難しくないと思います。
問題としては、そこそこ処理が重い点でしょうか。
私はコルーチンで15fpsで動作させてゲームに導入しています。
マルチスレッドの方が相応しいのでしょうが、Unityの一部機能が別スレッドでは使えない関係もあり導入は容易ではないと思います。
私はよくわからず妥協しました。
余談
今回の記事は、このブログの総アクセス数がキリ番を達成したので書きました。
閲覧頂きありがとうございます。アクセス数は励みです。
コメントもぜひ残していってください。