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 のコードはこんな感じになります。
(最初に決めたプロジェクト名が違う場合など、下のすべてをコピペしてもうまく動くとは限りません。念のため。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
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);
と書き換えると、処理していない画像を表示できます。