Windows フォームアプリ で OpenCvSharp 3 + Kinect v2 を使ってみる簡単な例です。たぶんこれが早いと思います。
Microsoft のサンプルはWPFのものが多いので、Windowsフォームを使う例としても残しておきます。
ソリューション一式はGitHubにも置いてあります。
環境
ここでは下記の環境での解説となっています。
それぞれ事前にインストールしておく必要があります。
- Visual Studio Community 2015 Upadte 1
- Kinect for Windows SDK 2.0 (Ver. 2.0.1410.19000)
1. 準備
1.1. プロジェクトの作成
Visual Studio を起動して 「ファイル」→「新規作成」→「プロジェクト」 を選びます。
出てきたウィンドウでは下記のように選び、適当な場所に適当な名前で作成します。
- 上部で「.NET Framework 4.5」
- 左のテンプレートは「Visual C#」
- 中央は「Windows フォームアプリケーション」
1.2. Microsoft.Kinect への参照の追加
新規プロジェクト作成できたら、ソリューションエクスプローラーでプロジェクトの下の「参照」(下図で青くなっている行)を右クリックして、「参照の追加」を選びます。
出てきたウィンドウで左は「アセンブリ」が選ばれた状態とし、右上の検索欄に「Kinect」と入れて「Microsoft.Kinect」を探します。
見つかった「Microsoft.Kinect」にマウスカーソルを持っていき、チェックを付けてOKを押します。
Microsoft.Kinect.Face など他のものもありますが、それは必要に応じてチェックします。(普通にカラー画像、深度画像、骨格を扱う範囲ではMicrosft.KinectだけでOKです。)
参照に追加できたら次へ進みます。
1.3. OpenCvSharp3 の追加
またソリューションエクスプローラーで、今度はプロジェクト(下図の青くなっている行)を右クリックし、「NuGet パッケージの管理」を選びます。
出てきたウィンドウの上部では「参照」を選んだ状態とし、検索欄に「OpenCvSharp3」と入れて探します。
「OpenCvSharp3-AnyCPU」を選んで「インストール」をします。
(マンドリルのアイコンです。)
インストールできれば、準備完了です。
2. フォームの編集
2.1. デザイン
Form1.cs を開いて、メインになるフォームに PictureBox を一つ追加しておきます。
その PictureBox を選択すると右上に小さい三角が出ますが、そこからサイズモードを Zoom にして、親コンテナーにドッキングしておくと良いでしょう。
2.2. コード
ソリューションエクスプローラーの Form1.cs を右クリックして「コードの表示」を選ぶとコード編集ができます。
Form1.cs のコードはこんな感じになります。
(最初に決めたプロジェクト名が違う場合など、下のすべてをコピペしてもうまく動くとは限りません。念のため。)
using System; using System.Drawing; using System.Windows.Forms; using Microsoft.Kinect; using OpenCvSharp; using OpenCvSharp.Extensions; namespace OpenCvKinectV2 { public partial class Form1 : Form { /// <summary> /// KinectSensorのインスタンス /// </summary> KinectSensor kinect; /// <summary> /// 最新のカラー画像 /// </summary> Mat colorImage; /// <summary> /// 出力用に処理後の画像 /// </summary> Mat colorOutputImage; /// <summary> /// PictureBoxで表示するBitmap /// </summary> Bitmap colorBitmap; public Form1() { InitializeComponent(); } /// <summary> /// ウィンドウが開いたときの処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { // KinectSensorのインスタンスを取得 this.kinect = KinectSensor.GetDefault(); // カラー、深度等をまとめて取得するイベントハンドラを設定 MultiSourceFrameReader multiSourceFrameReader = this.kinect.OpenMultiSourceFrameReader( FrameSourceTypes.Color // 今回はカラーのみ ); multiSourceFrameReader.MultiSourceFrameArrived += FrameArrived; // 画像の準備 InitializeImage(); // Kinect利用開始 this.kinect.Open(); } /// <summary> /// 画像を新規作成 /// </summary> private void InitializeImage() { // カラー画像の準備 FrameDescription colorFrameDescription = this.kinect.ColorFrameSource.FrameDescription; this.colorImage = new Mat( colorFrameDescription.Height, colorFrameDescription.Width, MatType.CV_8UC4 // 8ビット×4チャンネル分 ); this.colorImage.SetTo(Scalar.All(255)); // 最初は画像全体を白色に塗りつぶし // 同じサイズ・深度で出力用画像を作成 this.colorOutputImage = this.colorImage.Clone(); // カラー画像Bitmapの作成 this.colorBitmap = this.colorOutputImage.ToBitmap(); // PictureBoxへBitmapを割り当て this.pictureBox1.Image = this.colorBitmap; } /// <summary> /// Kinectのデータ取得時に呼ばれる処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FrameArrived(object sender, MultiSourceFrameArrivedEventArgs e) { MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame(); // カラー画像取得時の処理 using (ColorFrame colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame()) { if (colorFrame != null) { // OpenCVの画像にKinectのカラー画像を複製 colorFrame.CopyConvertedFrameDataToIntPtr( this.colorImage.Data, // カラー画像Matのデータ部分ポインタ (uint)(this.colorImage.Total() * this.colorImage.ElemSize()), // 全画素数 × 一画素のバイト数 ColorImageFormat.Bgra // RGBでなくBGRAの順番 ); // これでOpenCVでの画像処理ができる // (例としてRGBごとの閾値処理) Cv2.Threshold(this.colorImage, this.colorOutputImage, 127.0, 255.0, ThresholdTypes.Binary); // PictureBoxへ描画 UpdatePictureBox(this.colorOutputImage); } } } /// <summary> /// PictureBoxの表示を更新 /// <param name="image">表示画像。colorBitmapと同じサイズ・色深度でなければならない</param> /// </summary> private void UpdatePictureBox(Mat image) { // 指定された画像でBitmapを更新 image.ToBitmap(this.colorBitmap); // PictureBoxの描画を要求 this.pictureBox1.Invalidate(); } /// <summary> /// ウィンドウが閉じられたときの処理 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_FormClosed(object sender, FormClosedEventArgs e) { // Kinect利用終了 this.kinect.Close(); } } }
3. 実行
以上で Form1.cs のデザインとコードの編集ができたら、Kinect v2 をつないでデバッグの開始をしてみます。
上手く動けばこんな感じになります。
なお今回のサンプルでは上のコードでは、カラー画像そのままではなく R,G,B それぞれについて2値化する処理を入れてあります。
UpdatePictureBox(this.colorOutputImage);
の行を
UpdatePictureBox(this.colorImage);
と書き換えると、処理していない画像を表示できます。