Created
March 25, 2012 17:31
-
-
Save kjkmr/2198499 to your computer and use it in GitHub Desktop.
as3NUIでシンプルにRGB映像、深度、スケルトンを取得するためのサンプル。Kinectの設定やスケルトンのジョイント取得方法など日本語でコメント。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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