Skip to content

Instantly share code, notes, and snippets.

@tatsuro-ueda
Created January 31, 2012 05:33
Show Gist options
  • Save tatsuro-ueda/1709054 to your computer and use it in GitHub Desktop.
Save tatsuro-ueda/1709054 to your computer and use it in GitHub Desktop.
simple-OpenNI sample UserScene3d
// 骨格をを3次元描画する
import SimpleOpenNI.*;
SimpleOpenNI context;
float zoomF =0.5f;
float rotX = radians(180); // デフォルトでは視界をx軸に対して180度回転させる
// OpenNIのデータは反対から来る
float rotY = radians(0);
void setup()
{
size(1024,768,P3D); // strange, get drawing error in the cameraFrustum if i use P3D, in opengl there is no problem
context = new SimpleOpenNI(this);
// 鏡像にしない
context.setMirror(false);
// 深度カメラを有効にする
if(context.enableDepth() == false)
{
println("Can't open the depthMap, maybe the camera is not connected!");
exit();
return;
}
// すべての関節の骨格検出を有効にする
context.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
stroke(255,255,255);
smooth();
perspective(radians(45),
float(width)/float(height),
10,150000);
}
void draw()
{
// カメラ情報を更新する
context.update();
background(0,0,0);
// シーンの位置を設定する
translate(width/2, height/2, 0);
rotateX(rotX);
rotateY(rotY);
scale(zoomF);
int[] depthMap = context.depthMap();
int steps = 3; // 描画速度を上げるため、3点ごとに描画する
int index;
PVector realWorldPoint;
translate(0,0,-1000); // シーンの回転中心をカメラの1000mm前にする
stroke(100);
for(int y=0;y < context.depthHeight();y+=steps)
{
for(int x=0;x < context.depthWidth();x+=steps)
{
index = x + y * context.depthWidth();
if(depthMap[index] > 0)
{
// 投射された点を描画する
realWorldPoint = context.depthMapRealWorld()[index];
point(realWorldPoint.x,realWorldPoint.y,realWorldPoint.z);
}
}
}
// 可能であれば骨格を描画する
if(context.isTrackingSkeleton(1))
drawSkeleton(1);
// Kinectカメラを描画する
context.drawCamFrustum();
}
// 特定の関節にともなう骨格を描画する
void drawSkeleton(int userId)
{
strokeWeight(3);
// 3次元の関節データを取得するために
drawLimb(userId, SimpleOpenNI.SKEL_HEAD, SimpleOpenNI.SKEL_NECK);
drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_LEFT_SHOULDER);
drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_LEFT_ELBOW);
drawLimb(userId, SimpleOpenNI.SKEL_LEFT_ELBOW, SimpleOpenNI.SKEL_LEFT_HAND);
drawLimb(userId, SimpleOpenNI.SKEL_NECK, SimpleOpenNI.SKEL_RIGHT_SHOULDER);
drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_RIGHT_ELBOW);
drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_ELBOW, SimpleOpenNI.SKEL_RIGHT_HAND);
drawLimb(userId, SimpleOpenNI.SKEL_LEFT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_SHOULDER, SimpleOpenNI.SKEL_TORSO);
drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_LEFT_HIP);
drawLimb(userId, SimpleOpenNI.SKEL_LEFT_HIP, SimpleOpenNI.SKEL_LEFT_KNEE);
drawLimb(userId, SimpleOpenNI.SKEL_LEFT_KNEE, SimpleOpenNI.SKEL_LEFT_FOOT);
drawLimb(userId, SimpleOpenNI.SKEL_TORSO, SimpleOpenNI.SKEL_RIGHT_HIP);
drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_HIP, SimpleOpenNI.SKEL_RIGHT_KNEE);
drawLimb(userId, SimpleOpenNI.SKEL_RIGHT_KNEE, SimpleOpenNI.SKEL_RIGHT_FOOT);
strokeWeight(1);
}
void drawLimb(int userId,int jointType1,int jointType2)
{
PVector jointPos1 = new PVector();
PVector jointPos2 = new PVector();
float confidence;
// 関節の位置を描画する
confidence = context.getJointPositionSkeleton(userId,jointType1,jointPos1);
confidence = context.getJointPositionSkeleton(userId,jointType2,jointPos2);
stroke(255,0,0,confidence * 200 + 55);
line(jointPos1.x,jointPos1.y,jointPos1.z,
jointPos2.x,jointPos2.y,jointPos2.z);
drawJointOrientation(userId,jointType1,jointPos1,50);
}
void drawJointOrientation(int userId,int jointType,PVector pos,float length)
{
// 関節の方向を描画する
PMatrix3D orientation = new PMatrix3D();
float confidence = context.getJointOrientationSkeleton(userId,jointType,orientation);
if(confidence < 0.001f)
// 何も描画しない、方向のデータは役に立たない
return;
pushMatrix();
translate(pos.x,pos.y,pos.z);
// 局所の座標系を設定する
applyMatrix(orientation);
// 座標系の線の長さは100mm
// x軸 - 赤
stroke(255,0,0,confidence * 200 + 55);
line(0,0,0,
length,0,0);
// y軸 - 緑
stroke(0,255,0,confidence * 200 + 55);
line(0,0,0,
0,length,0);
// z軸 - 青
stroke(0,0,255,confidence * 200 + 55);
line(0,0,0,
0,0,length);
popMatrix();
}
// -----------------------------------------------------------------
// SimpleOpenNIユーザーイベント
void onNewUser(int userId)
{
println("onNewUser - userId: " + userId);
println(" start pose detection");
context.startPoseDetection("Psi",userId);
}
void onLostUser(int userId)
{
println("onLostUser - userId: " + userId);
}
void onStartCalibration(int userId)
{
println("onStartCalibration - userId: " + userId);
}
void onEndCalibration(int userId, boolean successfull)
{
println("onEndCalibration - userId: " + userId + ", successfull: " + successfull);
if (successfull)
{
println(" User calibrated !!!");
context.startTrackingSkeleton(userId);
}
else
{
println(" Failed to calibrate user !!!");
println(" Start pose detection");
context.startPoseDetection("Psi",userId);
}
}
void onStartPose(String pose,int userId)
{
println("onStartdPose - userId: " + userId + ", pose: " + pose);
println(" stop pose detection");
context.stopPoseDetection(userId);
context.requestCalibrationSkeleton(userId, true);
}
void onEndPose(String pose,int userId)
{
println("onEndPose - userId: " + userId + ", pose: " + pose);
}
// -----------------------------------------------------------------
// キーボードイベント
void keyPressed()
{
switch(key)
{
case ' ':
context.setMirror(!context.mirror());
break;
}
switch(keyCode)
{
case LEFT:
rotY += 0.1f;
break;
case RIGHT:
// zoom out
rotY -= 0.1f;
break;
case UP:
if(keyEvent.isShiftDown())
zoomF += 0.01f;
else
rotX += 0.1f;
break;
case DOWN:
if(keyEvent.isShiftDown())
{
zoomF -= 0.01f;
if(zoomF < 0.01)
zoomF = 0.01;
}
else
rotX -= 0.1f;
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment