unity for opencv 详细说明

https://qiita.com/utibenkei/items/290e83d2c50cdadbcb2d

※記事の情報を「OpenCV for Unity 2.0.9」に対応した内容に更新しました。

はじめに

前回の記事では、UnityでOpenCVを利用したアプリが簡単に作れるようになるAssetプラグイン「OpenCV for Unity」 (https://www.assetstore.unity3d.com/jp/#!/content/21088)のセットアップ方法を解説しましたが、今回の記事ではAssetに付属しているサンプルアプリのコードの中身を詳しく解説します。

特にUnityとOpenCVプラグインの連携のために用意されたユーティリティクラスやStreamingAssetsフォルダの使い方について解説したいと思います

サンプルアプリのコードを見る

AssetStoreでダウンロードできるAssetの中に付属しているサンプルアプリと同じものが、作者のGitHubでも公開されています。

収録サンプルの内容はチュートリアルビデオの後半部分を見ていただければ雰囲気で解ると思いますが、一応内容の一覧を載せておきます。

  • ArUcoSample (ArUcoクラスを利用したマーカーベースARサンプル)
  • BackgroundSubtractorMOG2Sample (背景差分取得のサンプル)
  • CamShiftSample (CamShift法による物体追跡のサンプル)
  • ComicFilterSample (いわゆる漫画風加工カメラのサンプル)
  • ConvexHullSample (凸包取得のサンプル)
  • DetectFaceSample (Haar-like特徴分類器を利用した顔検出のサンプル)
  • DrawingSample     (Matに対する図形や文字の描画のサンプル)
  • FaceRecognizerSample (顔認識のサンプル)
  • Feature2DSample (二つの画像の特徴点の対応付け結果を可視化するサンプル)
  • GrabCutSample (前景抽出サンプル)
  • HandPoseEstimationSample (HSV色空間による肌色検出や凸包と凸欠陥を利用して映っている手の指の本数を推定するサンプル)
  • HOGDescriptorSample (HOG特徴識別器を利用した人物検出のサンプル)
  • HoughLinesPSample (直線検出のサンプル)
  • InpaintSample (Inpaint関数を利用して画像内の不要な部分の除去をするサンプル)
  • MatchShapesSample (形状情報を用いたマッチング処理のサンプル)
  • MatchTemplateSample (テンプレートマッチング処理のサンプル)
  • MSERSample (MSER特徴量を利用した領域分割のサンプル)
  • MultiObjectTrackingBasedOnColorSample (色情報を基にした領域検出のサンプル)
  • OpticalFlowSample (Lucas-Kanade法によるオプティカルフローのサンプル)
  • PlotSample (Plotモジュールの利用サンプル)
  • SeamlessCloneSample (SeamlessCloneメソッドによる画像合成サンプル)
  • SimpleBlobSample (SimpleBlob検出器を使用した特徴点検出のサンプル)
  • StereoBMSample (BM法による視差画像の作成サンプル)
  • SVMSample (シンプルなサポートベクターマシンのサンプル)
  • Texture2DToMatSample (画像をMatに変換するサンプル)
  • ThresholdSample (閾値法による二値化処理のサンプル)
  • VideoCaptureSample (mjepg形式の動画ファイルを読み込んで表示するサンプル)
  • WebCamTextureAsyncDetectFaceSample (検出処理を別スレッド化した顔検出カメラのサンプル)
  • WebCamTextureDetectCirclesSample (円形検出カメラのサンプル)
  • WebCamTextureDetectFaceSample (顔検出カメラのサンプル)
  • WebCamTextureToMatHelperSample (ウェブカメラ画像をMatに変換するヘルパークラスの使い方サンプル)
  • WebCamTextureToMatSample (ウェブカメラ画像をMatに変換するサンプル)
  • WrapPerspectiveSample (透視変換処理のサンプル)

OpenCVを使った顔検出カメラのサンプルの解説

OpenCVの主な機能を使ったサンプルがいろいろ用意されていますが、OpenCVといったら顔検出(正確にはObjectDetection)が一番有名な機能だと思います。
そこで今回の記事ではウェブカメラのリアルタイム顔検出のサンプルであるWebCamTextureDetectFaceSampleのコードを例にして、「OpenCV for Unity」の具体的な使い方を解説したいと思います。

  顔検出カメラの処理手順
init() (初期化処理)
  webCamTextureを取得
  顔検出用のカスケード分類器("lbpcascade_frontalface.xml")をロード
   
Update () (毎フレーム実行される処理)
  webCamTextureのフレーム画像をMat形式に変換
  画像をグレースケールに変換
  画像に対して分類器で顔検出を行う
  検出された顔部分に赤い矩形を描画する
  Mat形式をTexture2D形式に変換して画面に表示
   

unity for opencv 详细说明_第1张图片

顔検出用のカスケード分類器("lbpcascade_frontalface.xml")をロード

WebCamTextureDetectFaceSample.cs(160行目付近)
cascade = new CascadeClassifier (Utils.getFilePath ("lbpcascade_frontalface.xml"));

オブジェクト検出をするための事前準備として、検出器の読み込みが必要になります。
検出器とは検出対象とするオブジェクトの特徴を機械学習によって蓄積させた学習データのことです。(カスケードファイルと呼ばれる.xmlファイル)
(検出器について詳しく知りたい方は、このスライドが解りやすいと思います)
今回のサンプルでは"lbpcascade_frontalface.xml"という正面顔検出用のカスケードファイルを読み込みます。

※オブジェクト検出に使用する検出器ファイルは、Assets/StreamingAssets/フォルダに入れておいてください。
「OpenCV for Unity」では実行時に動的に読み込むデータファイル類は、StreamingAssets/フォルダによってアプリのパッケージ内に含める必要があります。

WebCamTextureのフレーム画像をMat形式に変換 ~ 画像をグレースケールに変換

WebCamTextureDetectFaceSample.cs(195行目付近)
Utils.webCamTextureToMat (webCamTexture, rgbaMat, colors);

WebCamTextureの画像データをOpenCV内で取り扱えるようにするために、Asset独自のユーティリティクラスの中のUtils.webCamTextureToMatMat()メソッドを使って、Matという型に変換します。

※「OpenCV for Unity」にはUnity内で使用するの画像データクラス(Texture2D)とOpenCV内で使用する画像データクラス(Mat)を相互変換するためのユーティリティクラスが用意されています。
画像を加工するOpenCVアプリを作成する場合は、基本的にはこれらのクラスを使用して
(画像入力 → Texture →変換→ Mat(OpenCVで画像処理)→変換→ Texture → 表示出力)
というような流れで画像データを変換する必要があります。
WebCamTextureDetectFaceSample.cs(232行目付近)
Imgproc.cvtColor (rgbaMat, grayMat, Imgproc.COLOR_RGBA2GRAY);
Imgproc.equalizeHist (grayMat, grayMat);

グレースケールに変換するのは顔検出に不要な色情報を捨てて処理を高速化するためです。
さらにヒストグラムの平坦化を行い検出処理に適した画像情報に加工しています。

画像に対して分類器で顔検出を行う ~ 検出された顔部分に赤い矩形を描画する

WebCamTextureDetectFaceSample.cs(237行目付近)
cascade.detectMultiScale (grayMat, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
                              new Size (webCamTexture.height * 0.2, webCamTexture.height * 0.2), new Size ());

入力画像、検出結果を格納するMatOfRectオブジェクト、スケールファクタ、オブジェクトを構成する近傍矩形の最小数、処理モード、最小ウィンドウサイズを引数に入れて顔検出処理をします。

WebCamTextureDetectFaceSample.cs(241行目付近)
OpenCVForUnity.Rect[] rects = faces.toArray ();
for (int i = 0; i < rects.Length; i++) {
    Core.rectangle (rgbaMat, new Point (rects [i].x, rects [i].y), new Point (rects [i].x + rects [i].width, rects [i].y + rects [i].height), new Scalar (255, 0, 0, 255), 2);
}

検出された座標情報をもとに赤い矩形を描画します。

Mat形式をTexture2D形式に変換して画面に表示

WebCamTextureDetectFaceSample.cs(248行目付近)
Utils.matToTexture2D (rgbaMat, texture, colors);
WebCamTextureDetectFaceSample.cs(166行目付近)
gameObject.GetComponent<Renderer> ().material.mainTexture = texture;

顔検出処理を行ったMat形式の結果画像をAsset独自のユーティリティクラスを使ってTexture2D形式に戻します。
init()時にtextureを表示用のQuadのマテリアルのテクスチャにセットしてあるので、Update()の処理が毎フレーム繰り返されることで画面の表示が最新の画像に更新され続けます。

unity for opencv 详细说明_第2张图片

まとめ

  • 「OpenCV for Unity」では実行時に動的に読み込むデータファイルは、StreamingAssets/フォルダによってアプリのパッケージ内に含める必要がある
  • 「OpenCV for Unity」にはUnity内で使用するの画像データクラス(Texture2D)とOpenCV内で使用する画像データクラス(Mat)を相互変換するためのユーティリティクラスが存在するので、それを利用して画像処理を行う

今回の記事で取り上げなかった、他のサンプルコードについても基本的な処理の流れは共通しています。
OpenCVにおけるMat関連クラスの取り扱い方や数多く用意されている画像処理関数などについては、既に多くの解説サイトやQiitaの記事に情報が公開されていますので、そちらも参考にしてみてください。


你可能感兴趣的:(unity)