Skip to content

Instantly share code, notes, and snippets.

@kjkmr
Created March 25, 2012 17:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kjkmr/2198499 to your computer and use it in GitHub Desktop.
Save kjkmr/2198499 to your computer and use it in GitHub Desktop.
as3NUIでシンプルにRGB映像、深度、スケルトンを取得するためのサンプル。Kinectの設定やスケルトンのジョイント取得方法など日本語でコメント。
package
{
import com.as3nui.nativeExtensions.air.kinect.Kinect;
import com.as3nui.nativeExtensions.air.kinect.KinectSettings;
import com.as3nui.nativeExtensions.air.kinect.events.CameraImageEvent;
import com.as3nui.nativeExtensions.air.kinect.events.DeviceEvent;
import com.as3nui.nativeExtensions.air.kinect.data.SkeletonJoint;
import com.as3nui.nativeExtensions.air.kinect.data.User;
import com.as3nui.nativeExtensions.air.kinect.constants.CameraResolution;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Vector3D;
[SWF(frameRate="60", width="1280", height="960", backgroundColor="#FFFFFF")]
/*--------------------------------------------------
* Class AirKinectTutorial
--------------------------------------------------*/
public class AirKinectTutorial extends Sprite {
/*--------------------------------------------------
* 定数
--------------------------------------------------*/
public static const KINECT_MAX_DEPTH_IN_FLASH:uint = 2000; // Flashの3D空間での最大のZ値
/*--------------------------------------------------
* クラス変数
--------------------------------------------------*/
private var _device:Kinect; // Kinectデバイス
private var _rgbBitmap:Bitmap; // RGB表示用のBitmap
private var _depthBitmap:Bitmap; // Depth表示用のBitmap
private var _rgbSkeletonContainer:Sprite; // RGBに被せてスケルトン表示する用のSprite
private var _depthSkeletonContainer:Sprite; // 深度情報に被せてスケルトン表示する用のSprite
private var _skeletonContainer:Sprite; // スケルトンの3D表示用のSprite
/*--------------------------------------------------
* コンストラクタ
--------------------------------------------------*/
public function AirKinectTutorial() {
this.addEventListener( Event.ADDED_TO_STAGE, _onAddedToStage );
}
/*--------------------------------------------------
* 初期化
--------------------------------------------------*/
protected function _onAddedToStage( i_event:Event ):void {
trace("_onAddedToStage");
if ( Kinect.isSupported() ) {
trace("Kinect.isSupported");
// Kinectデバイス取得
_device = Kinect.getDevice();
// 表示オブジェクト生成
_rgbBitmap = new Bitmap();
addChild(_rgbBitmap);
_depthBitmap = new Bitmap();
addChild(_depthBitmap);
_depthBitmap.x = 640;
_rgbSkeletonContainer = new Sprite();
addChild(_rgbSkeletonContainer);
_depthSkeletonContainer = new Sprite();
addChild(_depthSkeletonContainer);
_depthSkeletonContainer.x = 640;
_skeletonContainer = new Sprite();
addChild(_skeletonContainer);
_skeletonContainer.y = 480;
// Kinectのイベント登録
_device.addEventListener(DeviceEvent.STARTED, _onKinectStarted, false, 0, true); // 開始
_device.addEventListener(DeviceEvent.STOPPED, _onKinectStopped, false, 0, true); // 停止
_device.addEventListener(CameraImageEvent.RGB_IMAGE_UPDATE, _onRgbUpdated, false, 0, true); // RGB映像取得
_device.addEventListener(CameraImageEvent.DEPTH_IMAGE_UPDATE, _onDepthUpdated, false, 0, true); // 深度情報取得
// Kinectの設定
var settings:KinectSettings = new KinectSettings();
settings.rgbEnabled = true; // RGBを有効に
settings.depthEnabled = true; // 深度情報を有効に
settings.depthShowUserColors = true; // 深度情報にユーザーの色を付けて表示
settings.skeletonEnabled = true; // スケルトンを有効に
settings.depthResolution = CameraResolution.RESOLUTION_640_480; // 深度情報の解像度を640x480に設定
/*
// 以下デフォルト設定
settings.depthEnabled = false; // 深度情報を有効にする
settings.depthResolution = CameraResolution.RESOLUTION_320_240; // 深度情報の解像度
settings.depthShowUserColors = false; // 深度情報にユーザーの色を付けて表示
settings.depthMirrored = true; // 深度情報を左右反転表示
settings.rgbEnabled = false; // RGB映像を有効にする
settings.rgbResolution = CameraResolution.RESOLUTION_640_480; // RGB映像の解像度
settings.rgbMirrored = true; // RGB映像を左右反転表示
settings.userEnabled = false; // ユーザーの取得を有効にする
settings.userMirrored = true; // ユーザーの情報を左右反転する
settings.skeletonEnabled = false; // スケルトンの取得を有効にする
settings.skeletonMirrored = true; // スケルトンの情報を左右反転する
settings.pointCloudEnabled = false; // ポイントクラウド(深度情報を3D空間にマッピングしたもの)を有効にする
settings.pointCloudResolution = CameraResolution.RESOLUTION_320_240; // ポイントクラウドの解像度
settings.pointCloudIncludeRGB = false; // ポイントクラウドをカラーにする
settings.pointCloudDensity = 1; // ポイントクラウドの密度
settings.pointCloudMirrored = true; // ポイントクラウドを左右反転する
settings.userMaskEnabled = false; // ユーザーのマスクを有効にする
settings.userMaskResolution = CameraResolution.RESOLUTION_320_240; // ユーザーのマスクの解像度
settings.userMaskMirrored = true; // ユーザーのマスクを左右反転表示
*/
// Kinectの開始
_device.start(settings);
// EnterFrameイベント
addEventListener(Event.ENTER_FRAME, _onEnterFrame, false, 0, true);
}
}
/*--------------------------------------------------
* Kinect開始時のイベントハンドラ
--------------------------------------------------*/
private function _onKinectStarted( i_event:DeviceEvent ):void {
trace("start");
}
/*--------------------------------------------------
* Kinect停止時のイベントハンドラ
--------------------------------------------------*/
private function _onKinectStopped( i_event:DeviceEvent ):void {
trace("stop");
}
/*--------------------------------------------------
* RGB映像更新時のイベントハンドラ
--------------------------------------------------*/
private function _onRgbUpdated( i_event:CameraImageEvent ):void {
_rgbBitmap.bitmapData = i_event.imageData;
}
/*--------------------------------------------------
* 深度情報更新時のイベントハンドラ
--------------------------------------------------*/
private function _onDepthUpdated( i_event:CameraImageEvent ):void {
_depthBitmap.bitmapData = i_event.imageData;
}
/*--------------------------------------------------
* EnterFrameのイベントハンドラ
--------------------------------------------------*/
private function _onEnterFrame( i_event:Event ):void {
// 表示オブジェクトを初期化
_rgbSkeletonContainer.graphics.clear();
_depthSkeletonContainer.graphics.clear();
_skeletonContainer.removeChildren();
// ユーザーの数だけループする
for each(var user:User in _device.users) {
// スケルトンを取得してる場合
if( user.hasSkeleton ) {
// スケルトンの各ジョイントごとにループ
for each(var joint:SkeletonJoint in user.skeletonJoints) {
// RGB映像に被せるジョイントの描画
_rgbSkeletonContainer.graphics.beginFill(0xFF0000);
_rgbSkeletonContainer.graphics.drawCircle(joint.rgbPosition.x, joint.rgbPosition.y, 5);
_rgbSkeletonContainer.graphics.endFill();
// 深度情報に被せるジョイントの描画
_depthSkeletonContainer.graphics.beginFill(0xFF0000);
_depthSkeletonContainer.graphics.drawCircle(joint.depthPosition.x, joint.depthPosition.y, 5);
_depthSkeletonContainer.graphics.endFill();
// ジョイントのZ座標を元に色を計算
var color:uint = (joint.positionRelative.z / (KINECT_MAX_DEPTH_IN_FLASH * 4)) * 255 << 16 | (1 - (joint.positionRelative.z / (KINECT_MAX_DEPTH_IN_FLASH * 4))) * 255 << 8 | 0;
// ジョイントの円のSpriteを生成
var jointSprite:Sprite = _createCircleForPosition(joint.positionRelative, color);
_skeletonContainer.addChild(jointSprite);
}
// 以下、指定したジョイントを取得する場合
/*
var head:SkeletonJoint = user.head; // 頭
var neck:SkeletonJoint = user.neck; // 首
var torso:SkeletonJoint = user.torso; // 胴
var leftShoulder:SkeletonJoint = user.leftShoulder; // 左肩
var leftElbow:SkeletonJoint = user.leftElbow; // 左ひじ
var leftHand:SkeletonJoint = user.leftHand; // 左手
var rightShoulder:SkeletonJoint = user.rightShoulder; // 右肩
var rightElbow:SkeletonJoint = user.rightElbow; // 右ひじ
var rightHand:SkeletonJoint = user.rightHand; // 右手
var leftHip:SkeletonJoint = user.leftHip; // 左尻
var leftKnee:SkeletonJoint = user.leftKnee; // 左ひざ
var leftFoot:SkeletonJoint = user.leftFoot; // 左足
var rightHip:SkeletonJoint = user.rightHip; // 右ケツ
var rightKnee:SkeletonJoint = user.rightKnee; // 右ひざ
var rightFoot:SkeletonJoint = user.rightFoot; // 右足
*/
}
//ユーザーの中央位置
var userCenterSprite:Sprite = _createCircleForPosition(user.positionRelative, 0xFF0000);
_skeletonContainer.addChild(userCenterSprite);
}
}
/*--------------------------------------------------
* スケルトン表示のための円を作成する
--------------------------------------------------*/
private function _createCircleForPosition(positionRelative:Vector3D, color:uint):Sprite {
var xPos:Number = ((positionRelative.x + 1) * .5) * 640;
var yPos:Number = ((positionRelative.y - 1) / -2) * 480;
var zPos:Number = positionRelative.z * KINECT_MAX_DEPTH_IN_FLASH;
var circle:Sprite = new Sprite();
circle.graphics.beginFill(color);
circle.graphics.drawCircle(0, 0, 15);
circle.graphics.endFill();
circle.x = xPos;
circle.y = yPos;
circle.z = zPos;
return circle;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment