示例教程

该Sample源码提供了 Orbbec Pose SDK 的开发示例,开发者可以依据sample更快地了解我们SDK提供的骨骼点跟踪相关功能及接口用法。

Windows/Linux

预期输出

_images/Sample_Windows.png

SDK使用的一般流程

1 使用SDK需要引入头文件。

#include <obt/obt.hpp>

2 应用启动时,获取license许可并初始化SDK库。在一个应用中只需要全局初始化一次。

// 从官方获取app_key、app_secret、auth_code,可在代码中硬编码也可从配置文件读取
const std::string app_key = "";
const std::string app_secret = "";
const std::string auth_code = "";

obt::License lic;
if (OBT_STATUS_OK != lic.acquire(app_key, app_secret, auth_code))
{
    printf("获取license失败\n");
    return false;
}

if (OBT_STATUS_OK != obt::initialize(lic))
{
    printf("库初始化失败\n");
    return false;
}

3 创建一个obt::Tracker实例对象,创建obt::Tracker实例对象需要指定若干配置项和摄像头内参。

3.1 每个摄像头的内参都不一样,实际项目中应该通过摄像头sdk提供的API函数获取,以下为示例数据。

    // Astra SDK实际内参获取:
    astra_get_orbbec_camera_params(streamConn_, &params);

    // Orbbec SDK实际内参获取:
    calibration_ = camera_.getCameraParam();

    // 默认值:
obt_calibration_t calibration;
calibration.fx = 572.08369;
calibration.fy = 575.66128;
calibration.cx = 320.0;
calibration.cy = 240.0;
calibration.color_width = 640;
calibration.color_height = 480;
calibration.depth_width = 640;
calibration.depth_height = 480;
calibration.depth_unit = OBT_DEPTH_1_MM;

3.2 指定创建Tracker的配置项,可以先获取缺省配置,然后仅修改关心的具体选项。

obt_configuration_t config;
obt_get_default_configuration(&config);
config.track_mode = OBT_TRACK_CENTER;
config.enable_profiler = false;

3.3 创建一个obt::Tracker实例对象,在一个应用中可以同时创建多个Tracker实例对象进行并发的业务处理。

obt::Tracker tracker;
if (OBT_STATUS_OK != tracker.create(config, calibration))
{
    printf("Tracker创建失败\n");
    return false;
}

4 开始进行业务处理。

while (!quit)
{
    obt::Capture capture;
    // TODO:获取一帧图像填充capture

    obt::Frame frame = tracker.process(capture);
    if (frame.isValid())
    {
        // TODO:使用frame做应用的业务逻辑
    }
}

5 结束应用前,别忘记释放SDK资源。

obt::terminate();

Android

预期输出

_images/Sample_Android.png

SDK使用的一般流程

1 使用SDK需要引入包。

package com.orbbec.ui;

import com.orbbec.obt.Body;
    import com.orbbec.obt.Calibration;
    import com.orbbec.obt.Capture;
    import com.orbbec.obt.DepthUnit;
    import com.orbbec.obt.Frame;
    import com.orbbec.obt.Image;
    import com.orbbec.obt.TrackMode;
    import com.orbbec.obt.Tracker;
    import com.orbbec.obt.Configuration;
import com.orbbec.obt.android.ObtAndroidContext;
    import com.orbbec.obt.License;

2 应用启动时,获取license许可并初始化SDK库。在一个应用中只需要全局初始化一次。

// 从官方获取app_key、app_secret、auth_code,可在代码中硬编码也可从配置文件读取
String appKey = mSharedPref.getString(KEY_APP_KEY, "");
String appSecret = mSharedPref.getString(KEY_APP_SECRET, "");
String authCode = mSharedPref.getString(KEY_AUTH_CODE, "");

License license = new License();
    if (license.acquire(appKey, appSecret, authCode)) {
            SharedPreferences.Editor editor = mSharedPref.edit();
            editor.putString(KEY_APP_KEY, appKey);
            editor.putString(KEY_APP_SECRET, appSecret);
            editor.putString(KEY_AUTH_CODE, authCode);
            editor.putBoolean(KEY_ACTIVATED, true);
            editor.commit();
            showPoseFragment(license);
            mActivateDialog.dismiss();
            Toast.makeText(mContext, "Active successfully !", Toast.LENGTH_LONG).show();
    } else {
            Toast.makeText(mContext, "Active failed, please try again !", Toast.LENGTH_LONG).show();
    }

private void showPoseFragment(License lic) {
    // TODO:显示预览界面

    mObtContext = new ObtAndroidContext(mContext);
    if (!mObtContext.initialize(lic)) {
        Log.e(TAG, "mObtContext initialize failed!");
    }
}

3 创建一个Tracker实例对象,创建Tracker实例对象需要指定若干配置项和摄像头内参。

3.1 每个摄像头的内参都不一样,实际项目中应该通过摄像头sdk提供的API函数获取,以下为示例数据。

public static Calibration AstraCalibration = new Calibration(572.08369f, 575.66128f, 320.0f, 240.0f, 640, 480, 640, 480, DepthUnit.DEPTH_1_MM);

    // Astra SDK实际内参获取:
    private OrbbecCameraParams mOrbbecCameraParams = null;
    mOrbbecCameraParams = mStreamSet.createDeviceController().GetOrbbecCameraParams();

    private Calibration loadCalibration(OrbbecCameraParams orbbecCameraParams, boolean isRotate) {
    Calibration calibration = new Calibration();
    calibration.colorWidth = isRotate ? GlobalDef.RESOLUTION_Y : GlobalDef.RESOLUTION_X;
    calibration.colorHeight = isRotate ? GlobalDef.RESOLUTION_X : GlobalDef.RESOLUTION_Y;
    calibration.depthWidth = isRotate ? GlobalDef.RESOLUTION_Y : GlobalDef.RESOLUTION_X;
    calibration.depthHeight = isRotate ? GlobalDef.RESOLUTION_X : GlobalDef.RESOLUTION_Y;
    calibration.depthUnit = DepthUnit.DEPTH_1_MM.getCode();

    calibration.fx = isRotate ? orbbecCameraParams.l_intr_p[1] : orbbecCameraParams.l_intr_p[0];
    calibration.fy = isRotate ? orbbecCameraParams.l_intr_p[0] : orbbecCameraParams.l_intr_p[1];
    calibration.cx = isRotate ? orbbecCameraParams.l_intr_p[3] : orbbecCameraParams.l_intr_p[2];
    calibration.cy = isRotate ? orbbecCameraParams.l_intr_p[2] : orbbecCameraParams.l_intr_p[3];

            // 获取不到实际的就使用默认的
    if (calibration.fx == 0 || calibration.fy == 0 || calibration.cx == 0 || calibration.cy == 0) {
        calibration.fx = isRotate ? GlobalDef.AstraCalibrationRotate.fx : GlobalDef.AstraCalibration.fx;
        calibration.fy = isRotate ? GlobalDef.AstraCalibrationRotate.fy : GlobalDef.AstraCalibration.fy;
        calibration.cx = isRotate ? GlobalDef.AstraCalibrationRotate.cx : GlobalDef.AstraCalibration.cx;
        calibration.cy = isRotate ? GlobalDef.AstraCalibrationRotate.cy : GlobalDef.AstraCalibration.cy;
    }
    return calibration;
}

    // Orbbec SDK实际内参获取:
    private CameraParams mCameraParams = new CameraParams();
    mDevice.getPropertyValueDataType(DeviceProperty.CAMERA_PARA, mCameraParams);

    private Calibration loadCalibration(CameraParams cameraParams, boolean isRotate) {
    Calibration calibration = new Calibration();
    calibration.colorWidth = isRotate ? GlobalDef.RESOLUTION_Y : GlobalDef.RESOLUTION_X;
    calibration.colorHeight = isRotate ? GlobalDef.RESOLUTION_X : GlobalDef.RESOLUTION_Y;
    calibration.depthWidth = isRotate ? GlobalDef.RESOLUTION_Y : GlobalDef.RESOLUTION_X;
    calibration.depthHeight = isRotate ? GlobalDef.RESOLUTION_X : GlobalDef.RESOLUTION_Y;
    calibration.depthUnit = DepthUnit.DEPTH_1_MM.getCode();
    float[] l_intr_p = cameraParams.getDepthInternalParams();

    calibration.fx = isRotate ? l_intr_p[1] : l_intr_p[0];
    calibration.fy = isRotate ? l_intr_p[0] : l_intr_p[1];
    calibration.cx = isRotate ? l_intr_p[3] : l_intr_p[2];
    calibration.cy = isRotate ? l_intr_p[2] : l_intr_p[3];

            // 获取不到实际的就使用默认的
    if (calibration.fx == 0 || calibration.fy == 0 || calibration.cx == 0 || calibration.cy == 0) {
        calibration.fx = isRotate ? GlobalDef.CALIBRATION_ROTATE.fx : GlobalDef.CALIBRATION.fx;
        calibration.fy = isRotate ? GlobalDef.CALIBRATION_ROTATE.fy : GlobalDef.CALIBRATION.fy;
        calibration.cx = isRotate ? GlobalDef.CALIBRATION_ROTATE.cx : GlobalDef.CALIBRATION.cx;
        calibration.cy = isRotate ? GlobalDef.CALIBRATION_ROTATE.cy : GlobalDef.CALIBRATION.cy;
    }
    return calibration;
}

3.2 指定创建Tracker的配置项,可以先获取缺省配置,然后仅修改关心的具体选项。

Configuration config = Configuration.getDefaultConfiguration();
config.setTrackMode(TrackMode.TRACK_FIRST);

3.3 创建一个obt::Tracker实例对象。

Tracker tracker = new Tracker(config, astraCalibration);

4 开始进行业务处理。

while (!mExit)
{
    Capture capture;
    // TODO:获取一帧图像填充capture

    Frame frame = tracker.process(capture);
    if (frame.isValid())
    {
        // TODO:使用frame做应用的业务逻辑
    }

            // TODO:使用完Capture和Frame后别忘记释放资源
            capture.close;
            frame.close;
}

5 结束应用前,别忘记释放SDK资源。

@Override
protected void onDestroy() {
    super.onDestroy();
    if (mObtContext != null) {
        mObtContext.terminate();
    }
}