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);
と書き換えると、処理していない画像を表示できます。







