using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using OpenNI;
using NITE;
namespace SwipeDetector
{
// アプリケーション固有の処理を記述
partial class Form1
{
// 設定ファイルのパス(環境に合わせて変更してください)
private const string CONFIG_XML_PATH = @"../../Data/SamplesConfig.xml";//C/あしぶみ/Data←あしぶみまでがカレントディレクトリ
private Context context;
private ImageGenerator image;
private SessionManager sessionManager;
private NITE.SwipeDetector swipeDetector;
//*****
private UserGenerator user;
private SkeletonCapability skelton;
private DepthGenerator depth;
private string pose = string.Empty;
private string message = "";
//*****
enum SessionState
{
NotInSession,
DetectSession,
InSession,
}
private SessionState sessionState = SessionState.NotInSession;
private Direction direction = Direction.Illegal;
// 描画用
private Brush brush = new SolidBrush(Color.Black);
private Font font = new Font("Arial", 30);
private PointF point = new Point(0, 0);
private Pen pen = new Pen(Color.Yellow, 8);
// 初期化
private void xnInitialize()
{
// コンテキストの初期化
context = new Context(CONFIG_XML_PATH);
// イメージジェネレータの作成
image = context.FindExistingNode(NodeType.Image) as ImageGenerator;
if (image == null) {
throw new Exception(context.GlobalErrorState);
}
//*****
//[Calibration]より
// デプスジェネレータの作成
depth = context.FindExistingNode(NodeType.Depth) as DepthGenerator;
if (depth == null) {
throw new Exception(context.GlobalErrorState);
}
// デプスの座標をイメージに合わせる
depth.AlternativeViewpointCapability.SetViewpoint(image);
//ユーザージェネレータの作成
user = context.FindExistingNode(NodeType.User) as UserGenerator;
//ユーザー検出機能をサポートしているか確認
if (!user.IsCapabilitySupported("User::Skeleton")) {
throw new Exception("ユーザー検出をサポートしていません");
}
// ユーザー認識のコールバックを登録
user.NewUser += new EventHandler
(user_NewUser);
user.LostUser += new EventHandler(user_LostUser);
//キャリブレーションにポーズが必要か確認
skelton = user.SkeletonCapability;
if (skelton.DoesNeedPoseForCalibration) {
// ポーズ検出のサポートチェック
if (!user.IsCapabilitySupported("User::PoseDetection")) {
throw new Exception("ユーザー検出をサポートしていません");
}
// キャリブレーションポーズの取得
pose = skelton.CalibrationPose;
// ポーズ検出のコールバックを登録
PoseDetectionCapability poseDetect = user.PoseDetectionCapability;
poseDetect.PoseDetected += new EventHandler(poseDetect_PoseDetected);
poseDetect.PoseEnded += new EventHandler(poseDetect_PoseEnded);
}
// キャリブレーションのコールバックを登録
skelton.CalibrationStart += new EventHandler(skelton_CalibrationStart);
skelton.CalibrationEnd += new EventHandler(skelton_CalibrationEnd);
// すべてをトラッキングする
skelton.SetSkeletonProfile(SkeletonProfile.All);
// ジェスチャーの検出開始
context.StartGeneratingAll();
//*****
// NITEのためのセッションマネージャを作成
sessionManager = new SessionManager(context, "Wave,Click", "RaiseHand");
// セッションの開始と終了を通知するコールバックを登録する
sessionManager.SessionStart += new EventHandler(sessionManager_SessionStart);
//new SessionManager.SessionStartHandler(sessionManager_SessionStart);
sessionManager.SessionEnd += new EventHandler(sessionManager_SessionEnd);
//new SessionManager.SessionEndHandler(sessionManager_SessionEnd);
sessionManager.SessionFocusProgress += new EventHandler(sessionManager_SessionFocusProgress);
//new SessionManager.SessionFocusProgressHandler(sessionManager_SessionFocusProgress);
// Wave(左右運動の検出器)
swipeDetector = new NITE.SwipeDetector();
swipeDetector.GeneralSwipe += new EventHandler(swipeDetector_GeneralSwipe);
//new SwipeDetector.GeneralSwipeHandler(swipeDetector_GeneralSwipe);
swipeDetector.SwipeUp += new EventHandler(swipeDetector_SwipeUp);
//new SwipeDetector.SwipeUpHandler(swipeDetector_SwipeUp);
swipeDetector.SwipeDown += new EventHandler(swipeDetector_SwipeDown);
//new SwipeDetector.SwipeDownHandler(swipeDetector_SwipeDown);
swipeDetector.SwipeRight += new EventHandler(swipeDetector_SwipeRight);
//new SwipeDetector.SwipeRightHandler(swipeDetector_SwipeRight);
swipeDetector.SwipeLeft += new EventHandler(swipeDetector_SwipeLeft);
//new SwipeDetector.SwipeLeftHandler(swipeDetector_SwipeLeft);
// リスナーに追加する
sessionManager.AddListener(swipeDetector);
// ジェネレータの動作を開始する
context.StartGeneratingAll();
}
string Houkou;//文字タイプの「Houkou」準備
// 描画
private unsafe void xnDraw()
{
// コンテキストとセッションマネージャーの更新
context.WaitAndUpdateAll();
sessionManager.Update(context);
// 画像データを取得する
ImageMetaData imageMD = image.GetMetaData();
//Calibration
SceneMetaData sceneMD = user.GetUserPixels(0);
// カメラ画像の作成
lock (this) {
// 書き込み用のビットマップデータを作成
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData data = bitmap.LockBits(rect, ImageLockMode.WriteOnly,
System.Drawing.Imaging.PixelFormat.Format24bppRgb);
// 生データへのポインタを取得
byte* dst = (byte*)data.Scan0.ToPointer();
byte* src = (byte*)image.ImageMapPtr.ToPointer();
//*****
//ushort* label = (ushort*)sceneMD.LabelMapPtr.ToPointer();
for (int i = 0; i < imageMD.DataSize; i += 3, src += 3, dst += 3)//,++label) {
{
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
}
bitmap.UnlockBits(data);
//Calibration
// スケルトンの描画
foreach (int id in user.GetUsers()) {
// トラッキング対象のユーザーでなければ次へ
if (!user.SkeletonCapability.IsTracking(id)) {
continue;
}
/*DrawLine(id, SkeletonJoint.Head, SkeletonJoint.Neck);//頭、首
DrawLine(id, SkeletonJoint.Neck, SkeletonJoint.LeftShoulder);//首、左肩
DrawLine(id, SkeletonJoint.LeftShoulder, SkeletonJoint.LeftElbow);//左肩、左腕
DrawLine(id, SkeletonJoint.LeftElbow, SkeletonJoint.LeftHand);//左腕、左手
DrawLine(id, SkeletonJoint.Neck, SkeletonJoint.RightShoulder);//首、右肩
DrawLine(id, SkeletonJoint.RightShoulder, SkeletonJoint.RightElbow);//右肩、右腕
DrawLine(id, SkeletonJoint.RightElbow, SkeletonJoint.RightHand);//右腕、右手
DrawLine(id, SkeletonJoint.LeftShoulder, SkeletonJoint.Torso);//左肩、胴
DrawLine(id, SkeletonJoint.RightShoulder, SkeletonJoint.Torso);//右肩、胴*/
DrawLine(id, SkeletonJoint.Torso, SkeletonJoint.LeftHip);//胴、左おしり
DrawLine(id, SkeletonJoint.LeftHip, SkeletonJoint.LeftKnee);//左おしり、左ひざ
DrawLine(id, SkeletonJoint.LeftKnee, SkeletonJoint.LeftFoot);//左ひざ、左足
DrawLine(id, SkeletonJoint.Torso, SkeletonJoint.RightHip);//胴、右おしり
DrawLine(id, SkeletonJoint.RightHip, SkeletonJoint.RightKnee);//右おしり、右ひざ
DrawLine(id, SkeletonJoint.RightKnee, SkeletonJoint.RightFoot);//右ひざ、右足
DrawLine(id, SkeletonJoint.LeftHip, SkeletonJoint.RightHip);//左おしり、右おしり
}
//*****
// 現在の状態を表示する
Graphics g = Graphics.FromImage(bitmap);
string message1 = message+"\r\n"+
sessionState.ToString() + "\r\n" +
direction.ToString();
string messageKyukei = message+"\r\n"+
sessionState.ToString() + "\r\n" +
"休憩 (*´-д-)ゞ";
if(Houkou == "Right")
{
g.DrawString(messageKyukei, font, brush, new Point(0, 0));
}
else if (Houkou == "Left")
{
g.DrawString(messageKyukei, font, brush, new Point(0, 0));
}
else
{
g.DrawString(message1, font, brush, new Point(0, 0));
}
}
}
// キーイベント
private void xnKeyDown(Keys key)
{
}
//*****
// ユーザー検出
void user_NewUser(object sender, NewUserEventArgs e)//ProductionNode node, int id
{
message = "ユーザー検出:" + e.ID;
// ポーズの検出が必要であれば、ポーズの検出を開始する
if (!string.IsNullOrEmpty(pose))
{
user.PoseDetectionCapability.StartPoseDetection(pose, e.ID);
}
// ポーズの検出が不要であれば、キャリブレーションを開始する
else
{
user.SkeletonCapability.RequestCalibration(e.ID, true);
}
}
// ユーザー消失
void user_LostUser(object sender, UserLostEventArgs e)
{
message = "ユーザー消失:" + e.ID;
}
// ポーズ検出
void poseDetect_PoseDetected(object sender, PoseDetectedEventArgs e)
{
message = "ポーズ検出:" + e.Pose + " ユーザー:" + e.ID;
// ポーズの検出を停止し、キャリブレーションを開始する
user.PoseDetectionCapability.StopPoseDetection(e.ID);
user.SkeletonCapability.RequestCalibration(e.ID, true);
}
// ポーズ検出終了
void poseDetect_PoseEnded(object sender, PoseEndedEventArgs e)
{
message = "ポーズ消失:" + e.Pose + " ユーザー:" + e.ID;
}
// キャリブレーション開始
void skelton_CalibrationStart(object sender, CalibrationStartEventArgs e)
{
message = "キャリブレーション開始:" + e.ID;
}
// キャリブレーション終了
void skelton_CalibrationEnd(object sender, CalibrationEndEventArgs e)
{
// キャリブレーション成功
if (e.Success)
{
message = "キャリブレーション成功:" + e.ID;
user.SkeletonCapability.StartTracking(e.ID);
}
// キャリブレーション失敗
else
{
message = "キャリブレーション失敗:" + e.ID;
}
}
// 骨格の線を引く
void DrawLine(int player, SkeletonJoint eJoint1, SkeletonJoint eJoint2)
{
// 各箇所の座標を取得する
SkeletonJointPosition joint1 = skelton.GetSkeletonJointPosition(player, eJoint1);
SkeletonJointPosition joint2 = skelton.GetSkeletonJointPosition(player, eJoint2);
/*skelton.GetSkeletonJointPosition(player, eJoint1, ref joint1);
skelton.GetSkeletonJointPosition(player, eJoint2, ref joint2);*/
if (joint1.Confidence < 0.5 || joint2.Confidence < 0.5) {
return;
}
// 現実の座標から画面の座標に変換する
Point3D[] pt = new Point3D[] { joint1.Position, joint2.Position };
pt = depth.ConvertRealWorldToProjective(pt);
Graphics g = Graphics.FromImage(bitmap);
g.DrawLine(pen, pt[0].X, pt[0].Y, pt[1].X, pt[1].Y);
}
//*****
// 左方向への動きを通知する
void swipeDetector_SwipeLeft(object sender,VelocityAngleEventArgs e)//float velocity, float angle)
{
//brush = new SolidBrush(Color.Red);
}
// 右方向への動きを通知する
void swipeDetector_SwipeRight(object sender,VelocityAngleEventArgs e)//float velocity, float angle)
{
//brush = new SolidBrush(Color.Blue);
}
// 下方向への動きを通知する
void swipeDetector_SwipeDown(object sender,VelocityAngleEventArgs e)//float velocity, float angle)
{
brush = new SolidBrush(Color.Yellow);
}
// 上方向への動きを通知する
void swipeDetector_SwipeUp(object sender,VelocityAngleEventArgs e)//float velocity, float angle)
{
brush = new SolidBrush(Color.Yellow);
}
// スワイプの検出を通知する
void swipeDetector_GeneralSwipe(object sender,DirectionVelocityAngleEventArgs e)//Direction dir, float velocity, float angle)
{
//検出するときに、e.Directionでイベントで来た方向をToString()にいれこんで文字タイプに変換する
Houkou=e.Direction.ToString();
if (Houkou =="Right" )//Directionが「右」だったら何もしない(命令しない)
{
}
else if (Houkou == "Left")//Directionが「左」だったら何もしない(命令しない)
{
}
else//他のやつ=上下だったら普通に方向を描画する
{
direction = e.Direction;
}
}
// セッションの開始を通知する
void sessionManager_SessionStart(object sender,PositionEventArgs e)//ref Point3D position)
{
sessionState = SessionState.InSession;
}
// セッションの終了を通知する
void sessionManager_SessionEnd(object sender,EventArgs e)
{
sessionState = SessionState.NotInSession;
}
// セッションフォーカスの検出を通知する
void sessionManager_SessionFocusProgress(object sender,SessionProgressEventArgs e)//string strFocus,ref Point3D ptPosition, float fProgress)
{
sessionState = SessionState.DetectSession;
}
}
}