jmonkeyengineでopenni(kinect)を使う

openniも2.xとメジャーバージョンアップにより、結構変わったようです。

Kinectトラッキング画像

こちらで試した環境。

  • CPU : intel core-i7 2600k
  • グラフィック : AMD Radeon HD 7750 (Catalyst 13.9)
  • OS : Windows7 64bit
  • Java: 1.7.0_11; Java HotSpot™ 64-Bit Server VM 23.6-b04
  • Runtime: Java™ SE Runtime Environment 1.7.0_11-b21
  • jMonkeyEngine Product Version: jMonkeyEngine SDK 3.0
  • OpenNI : 2.2 ×64
  • Nite : 2.2 ×64
  • トラッキングデバイス : kinect for xbox360 (KinectSDK 1.7)

ダウンロード&インストール

以下のファイルをダウンロードし、インストールする。

  1. OpenNI2
  2. NITE
  3. KinectSDK

jmonkeyengineでプロジェクトを作成。

新規プロジェクト => JME3 => BasicGame を選択。プロジェクト名を入力し作成する。
C:\Program Files\OpenNI2\Redist 以下のファイルをコピーした後、JMEで ファイル タブを選択し、プロジェクト直下にペースト。
C:\Program Files\PrimeSense\NiTE2\Redist 以下のファイルも同様にペースト。
上記ファイルのうち、pdbファイルはいらない。

以下のコードをsrcフォルダ内のmygame/Main.java内に記述

 
package mygame;
 
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.primesense.nite.JointType;
import com.primesense.nite.NiTE;
import com.primesense.nite.SkeletonState;
import com.primesense.nite.UserData;
import com.primesense.nite.UserTracker;
import com.primesense.nite.UserTrackerFrameRef;
import java.util.ArrayList;
import org.openni.OpenNI;
import java.util.List;
import org.openni.DeviceInfo;
import org.openni.Device;
 
 
public class Main extends SimpleApplication implements UserTracker.NewFrameListener {
 
    Device device;
    UserTracker mTracker;
    UserTrackerFrameRef mLastFrame;
 
    BitmapText infoText;
    BitmapText headText;
 
    /**
     * 関節
     */
    JointType[] bodyParts = {
        JointType.HEAD,
        JointType.NECK,
 
        JointType.LEFT_SHOULDER,
        JointType.LEFT_ELBOW,
        JointType.LEFT_HAND,
 
        JointType.RIGHT_SHOULDER,
        JointType.RIGHT_ELBOW,
        JointType.RIGHT_HAND,
 
        JointType.TORSO,
 
        JointType.LEFT_HIP,
        JointType.LEFT_KNEE,
        JointType.LEFT_FOOT,
 
        JointType.RIGHT_HIP,
        JointType.RIGHT_KNEE,
        JointType.RIGHT_FOOT
    };
 
    /**
     * 関節ボックス
     */
    ArrayList<Geometry> gb = new ArrayList<Geometry>();
 
    public void onNewFrame(UserTracker ut) {
        if (mLastFrame != null) {
            mLastFrame.release();
            mLastFrame = null;
        }
 
        mLastFrame = mTracker.readFrame();
        for (UserData user : mLastFrame.getUsers()) {
            if (user.isNew()) {
                mTracker.startSkeletonTracking(user.getId());
                headText.setText("Tracking Users : "+mLastFrame.getUsers().size());
            }
        }
 
    }
 
    public static void main(String[] args) {
        Main app = new Main();
        app.start();
 
    }
 
    @Override
    public void simpleInitApp() {
 
        //関節用ボックスの準備
        for(int i = 0; i < bodyParts.length; i++)
        {
 
            Box box = new Box(Vector3f.ZERO, 0.1f, 0.1f, 0.1f);
 
            gb.add(i, new Geometry("Box", box));
 
            Material mat = new Material(assetManager,
                "Common/MatDefs/Misc/Unshaded.j3md");
            mat.setColor("Color", ColorRGBA.Yellow);
            gb.get(i).setMaterial(mat);
            rootNode.attachChild(gb.get(i));
        }
 
        guiNode.detachAllChildren();
        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
 
        infoText = new BitmapText(guiFont, false);
        infoText.setSize(guiFont.getCharSet().getRenderedSize() * 2);
        infoText.setText("Info");
 
        infoText.setLocalTranslation(settings.getWidth() / 3, infoText.getLineHeight(), 0);
        guiNode.attachChild(infoText);
 
 
        headText = new BitmapText(guiFont, false);
        headText.setSize(guiFont.getCharSet().getRenderedSize() * 2);
        headText.setLocalTranslation(10, settings.getHeight() - 10, 0);
        headText.setText("test");
        guiNode.attachChild(headText);
 
 
        OpenNI.initialize();
        NiTE.initialize();
 
        List<DeviceInfo> devicesInfo = OpenNI.enumerateDevices();
        if (devicesInfo.isEmpty()) {
            infoText.setText("Device is not found.");
 
            return;
        }
 
 
        device = Device.open(devicesInfo.get(0).getUri());
        device.getDeviceInfo().getName();
        mTracker = UserTracker.create();
        infoText.setText("Device:" + device.getDeviceInfo().getName());
        mTracker.addNewFrameListener(this);
 
    }
 
    @Override
    public void simpleUpdate(float tpf) {
        if (mLastFrame == null) {
            return;
        }
 
        for (UserData user : mLastFrame.getUsers()) {
 
        	if (user.getSkeleton().getState() == SkeletonState.TRACKED) {
 
                    for(int i = 0; i < bodyParts.length; i++)
                    {
                        movePoint(user, i);
                    }
 
        	}
        }
 
    }
 
    /**
     * 関節の動作
     *
     * @param user
     * @param joinNum
     */
    private void movePoint(UserData user, int joinNum)
    {
 
        com.primesense.nite.SkeletonJoint joint = user.getSkeleton().getJoint(bodyParts[joinNum]);
        if (joint.getPositionConfidence() < 0.5f) {
    		return;
    	}
 
        com.primesense.nite.Point2D<Float> pos = mTracker.convertJointCoordinatesToDepth(joint.getPosition());
 
        gb.get(joinNum).setLocalTranslation(
                ((pos.getX() )/100) - 3.5f  ,
                -((pos.getY()) /100)+1.5f ,
                0f);
 
 
    }
 
 
    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }
 
 
}
 

あとはエディタ内で右クリック => ファイルをデバッグで、関節のトラッキングデモが実行可能。