Linux C++

开发环境搭建

  • Ubuntu18.04系统

接入说明

您需要按照如下流程完成应用的开发工作

  1. License申请

使用算法SDK前需要申请对应的License,否则无法正常使用

  1. 集成基础SDK

用于获取设备的数据流,基础SDK主要分为Astra SDK和Orbbec SDK,具体需要根据实际选用的模组来选择基础SDK进行集成

  • Astra SDK用于Astra Plus和Astra Mini设备的控制和取流操作

  • Orbbec SDK用于Astra+和Femto设备的控制和取流操作

  1. 集成算法SDK

  • 算法SDK用于骨架识别

基础SDK

Astra SDK使用示例

摄像头sdk初始化配置

status = astra_initialize();
status = astra_streamset_open("device/default", &streamConn_);
status = astra_reader_create(streamConn_, &reader_);

status = astra_reader_get_colorstream(reader_, &colorStream_);
status = astra_reader_get_depthstream(reader_, &depthStream_);
//开d2c对齐
status = astra_depthstream_set_registration(depthStream_, true);
//配置流参数
status = astra_imagestream_get_mode(colorStream_, &mode);
mode.width = width;
mode.height = height;
mode.fps = fps;
mode.pixelFormat = 200;
status = astra_imagestream_set_mode(colorStream_, &mode);
status = astra_imagestream_get_mode(depthStream_, &mode);
mode.width = DEFAULT_WIDTH;
mode.height = DEFAULT_HEIGHT;
mode.fps = fps;
mode.pixelFormat = 100;
status = astra_imagestream_set_mode(depthStream_, &mode);

status = astra_stream_start(colorStream_);
status = astra_stream_start(depthStream_);

astra_reader_callback_id_t callbackId;
astra_reader_register_frame_ready_callback(reader_, frameReady, NULL, &callbackId); //frameReady为取流的回调函数

获取摄像头内参

obt_calibration_t AstraCamera:: getCameraParam()
{
    orbbec_camera_params params;
    //astra_get_orbbec_camera_params(streamConn_, &params)为从基础sdk获取内参,每个相机内参不一样,同一型号的不同相机内参也会有差别,每个相机都需要获取内参
    astra_status_t status = astra_get_orbbec_camera_params(streamConn_, &params);
    //从基础sdk获取相机内参成功,就把获取的fx,fy,cx,cy赋值给calibration_,获取失败,就使用默认的calibration_
    if(status == 0){
        if(params.r_intr_p[0] > 0.0f)
            calibration_.fx = params.r_intr_p[0];
        if(params.r_intr_p[1] > 0.0f)
            calibration_.fy = params.r_intr_p[1];
        if(params.r_intr_p[2] > 0.0f)
            calibration_.cx = params.r_intr_p[2];
        if(params.r_intr_p[3] > 0.0f)
            calibration_.cy = params.r_intr_p[3];
    }
    calibration_.color_width = IMAGE_WIDTH;
    calibration_.color_height = IMAGE_HEIGHT;
    calibration_.depth_width = IMAGE_WIDTH;
    calibration_.depth_height = IMAGE_HEIGHT;
    calibration_.depth_unit = OBT_DEPTH_1_MM;
    //calibration_给算法使用
    return calibration_;
}

摄像头sdk取流

//通过回调函数取流,frame为从回调函数获取的帧数据
astra_frame_get_colorframe(frame, &colorFrame);
status = astra_colorframe_get_data_rgb_ptr(colorFrame, (astra_rgb_pixel_t**)&colorData, &length);
status = astra_colorframe_get_metadata(colorFrame, (astra_image_metadata_t*)&colorMeta);
astra_frame_get_depthframe(frame, &depthFrame);
status = astra_depthframe_get_metadata(depthFrame, (astra_image_metadata_t*)&depthMeta);
status = astra_depthframe_get_data_ptr(depthFrame,(int16_t**)&depthData, &length);

Orbbec SDK使用示例

摄像头sdk初始化配置

auto devList = ctx.queryDeviceList();
int count = devList->deviceCount();
if (devList->deviceCount() == 0) {
    return false;
}
auto dev = devList->getDevice(0);
if (nullptr == dev){
    return false;
}
if(dev->isPropertySupported(OB_PROP_COLOR_AUTO_EXPOSURE_PRIORITY_INT,OB_PERMISSION_WRITE)){
    dev->setIntProperty(OB_PROP_COLOR_AUTO_EXPOSURE_PRIORITY_INT, 0);
}
pipe_ = std::make_shared<ob::Pipeline>(dev);
//配置流参数
auto colorProfiles = pipe_->getStreamProfileList(OB_SENSOR_COLOR);
std::shared_ptr<ob::VideoStreamProfile> colorProfile = nullptr;
for(int i = 0; i < colorProfiles->count(); i++) {
    auto profile = colorProfiles->getProfile(i)->as<ob::VideoStreamProfile>();
    if((profile->format() == OB_FORMAT_RGB888) &&
            profile->width() == width && profile->height() == height) {
        colorProfile = profile;
        break;
    }
}
if(!colorProfile) {
    colorProfile = colorProfiles->getProfile(0)->as<ob::VideoStreamProfile>();
}
auto depthProfiles = pipe_->getStreamProfileList(OB_SENSOR_DEPTH);
std::shared_ptr<ob::VideoStreamProfile> depthProfile = nullptr;
for(int i = 0; i < depthProfiles->count(); i++) {
    auto profile = depthProfiles->getProfile(i)->as<ob::VideoStreamProfile>();
    if((profile->format() == OB_FORMAT_YUYV || profile->format() == OB_FORMAT_Y16) &&
            profile->width() == DEFAULT_WIDTH && profile->height() == DEFAULT_HEIGHT && profile->fps() == fps) {
        depthProfile = profile;
        break;
    }
}
if(!depthProfile) {
    depthProfile = depthProfiles->getProfile(0)->as<ob::VideoStreamProfile>();
}
std::shared_ptr<ob::Config> config = std::make_shared<ob::Config>();
config->enableStream(colorProfile);
config->enableStream(depthProfile);
//开d2c对齐
config->setAlignMode(ALIGN_D2C_HW_MODE);

try{
    pipe_->enableFrameSync();//默认开帧同步,femto支持,astra+不支持
}catch(ob::Error &e) {
    std::cerr << "function:" << e.getName() << "\nargs:" << e.getArgs() << "\nmessage:" << e.getMessage() << "\ntype:" << e.getExceptionType() << std::endl;
}

pipe_->start(config, callback); //callback为取流的回调函数

获取摄像头内参

obt_calibration_t OrbbecCamera:: getCameraParam()
{
    if(!pipe_){
        return calibration_;
    }
    //pipe_->getCameraParam()为从基础sdk获取内参,每个相机内参不一样,同一型号的不同相机内参也会有差别,每个相机都需要获取内参
    OBCameraParam cameraParam = pipe_->getCameraParam();
    OBCameraIntrinsic colorIntrinsic = cameraParam.rgbIntrinsic;
    OBCameraIntrinsic depthIntrinsic = cameraParam.depthIntrinsic;

    float scale = colorWidth_*1.0f/colorIntrinsic.width;
    setValue(calibration_.fx, depthIntrinsic.fx*scale);
    setValue(calibration_.fy, depthIntrinsic.fy*scale);
    setValue(calibration_.cx, depthIntrinsic.cx*scale);
    setValue(calibration_.cy, depthIntrinsic.cy*scale);
    setValue(calibration_.color_width, (int)(colorIntrinsic.width*scale));
    setValue(calibration_.color_height, (int)(colorIntrinsic.height*scale));
    setValue(calibration_.depth_width, (int)(depthIntrinsic.width*scale));
    setValue(calibration_.depth_height, (int)(depthIntrinsic.height*scale));
    //calibration_为经过转换后的内参,给算法使用
    return calibration_;
}

摄像头sdk取流

//通过回调函数取流,frameSet为从回调函数获取的帧数据
auto colorFrame = frameSet->colorFrame();
auto depthFrame = frameSet->depthFrame();

算法SDK

算法SDK使用示例

应用启动时,首先设置license

if (OBT_STATUS_OK != obt_set_license(appKey, appSecret, authCode)) {
    return false;
}

对算法库进行初始化,在一个进程中只需要全局初始化一次

if (OBT_STATUS_OK != obt::initialize()) {
    return false;
}

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

obt::Tracker tracker_;
if (OBT_STATUS_OK != tracker_.create()){
    return false;
}

配置tracker实例对象

//设置跟踪模式。
tracker_.setMode(trackMode_);
//设置是否输出mask数据
tracker_.setOutputtingMask(enableMask);
//设置相机内参,参考基础sdk获取内参的方法,3D模式的骨架需要设置相机内参,2D模式的骨架不需要设置相机内参
tracker_.setCalibration(&calibration_);
//设置滤波
tracker_.setSmoothingFactor(smoothingFactor_);

数据传入算法

//摄像头sdk取流时创建的Image,传给算法处理,得到Frame,Frame用于获取绘制骨架
//2D模式
frame = tracker_.process(color);
//3D模式
frame = tracker_.process(color,depth);

获取算法运行结果

//从算法处理后的Frame获取Image
Image colorImage = frame.getColor();
//从算法处理后的Frame获取骨架
//2D模式
bodies = frame.getColorBodyList();
//3D模式
bodies = frame.getDepthBodyList();

Tracker实例对象使用结束后,需要释放

tracker_.destroy();

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

obt::terminate();