创建您的第一个相机预览应用
  • PG电子

  • PG电子

    创建您的第一个相机预览应用

    本快速入门指南将引导您通过使用Orbbec SDK 获取相机多路流。该文档参考了C++示例MultiStream。

     

     

    先决条件

    连接Orbbec设备。
    下载并安装Orbbec SDK。

     

     

    头文件

    包含Orbbec SDK的主要头文件:

    #include "window.hpp"

    #include "libobsensor/hpp/Pipeline.hpp"
    #include "libobsensor/hpp/Error.hpp"
    #include <mutex>
    #include <thread>

     

    初始化Pipeline

     

        // Create a pipeline with default device
        ob::Pipeline pipe;

        // Configure which streams to enable or disable for the Pipeline by creating a Config
        std::shared_ptr<ob::Config> config = std::make_shared<ob::Config>();

     

     

    配置流

     

    根据设备上可用的sensor配置要启用哪些流。

     

        auto device     = pipe.getDevice();
        auto sensorList = device->getSensorList();
        for(int i = 0; i < sensorList->count(); i++) {
            auto sensorType = sensorList->type(i);
            if(sensorType == OB_SENSOR_GYRO || sensorType == OB_SENSOR_ACCEL) {
                continue;
            }
            auto profiles = pipe.getStreamProfileList(sensorType);
            auto profile  = profiles->getProfile(OB_PROFILE_DEFAULT);
            config->enableStream(profile);
        }

     

     

    Start Pipeline

    启动配置了视频流的Pipeline。

        // Start the pipeline with config
        std::mutex                                        frameMutex;
        std::map<OBFrameType, std::shared_ptr<ob::Frame>> frameMap;
        pipe.start(config, [&](std::shared_ptr<ob::FrameSet> frameset) {
            auto count = frameset->frameCount();
            for(int i = 0; i < count; i++) {
                auto                         frame = frameset->getFrame(i);
                std::unique_lock<std::mutex> lk(frameMutex);
                frameMap[frame->type()] = frame;
            }
        });

     

    获取IMU 数据

    由于 IMU 传感器帧率高,单独处理IMU数据。

       auto                                              dev         = pipe.getDevice();
        auto                                              imuPipeline = std::make_shared<ob::Pipeline>(dev);
        std::mutex                                        imuFrameMutex;
        std::map<OBFrameType, std::shared_ptr<ob::Frame>> imuFrameMap;
        try {
            auto                        accelProfiles = imuPipeline->getStreamProfileList(OB_SENSOR_ACCEL);
            auto                        gyroProfiles  = imuPipeline->getStreamProfileList(OB_SENSOR_GYRO);
            auto                        accelProfile  = accelProfiles->getProfile(OB_PROFILE_DEFAULT);
            auto                        gyroProfile   = gyroProfiles->getProfile(OB_PROFILE_DEFAULT);
            std::shared_ptr<ob::Config> imuConfig     = std::make_shared<ob::Config>();
            imuConfig->enableStream(accelProfile);
            imuConfig->enableStream(gyroProfile);
            imuPipeline->start(imuConfig, [&](std::shared_ptr<ob::FrameSet> frameset) {
                auto count = frameset->frameCount();
                for(int i = 0; i < count; i++) {
                    auto                         frame = frameset->getFrame(i);
                    std::unique_lock<std::mutex> lk(imuFrameMutex);
                    imuFrameMap[frame->type()] = frame;
                }
            });
        }
        catch(...) {
            std::cout << "IMU sensor not found!" << std::endl;
            imuPipeline.reset();
        }

     

    渲染帧

    创建一个用于渲染收集到的帧的窗口:

        Window app("MultiStream", 1280, 720, RENDER_GRID);
        while(app) {
            std::vector<std::shared_ptr<ob::Frame>> framesForRender;
            {
                std::unique_lock<std::mutex> lock(frameMutex);
                for(auto &frame: frameMap) {
                    framesForRender.push_back(frame.second);
                }
            }
            {
                std::unique_lock<std::mutex> lock(imuFrameMutex);
                for(auto &frame: imuFrameMap) {
                    framesForRender.push_back(frame.second);
                }
            }
            app.addToRender(framesForRender);
        }

     

     

    停止Pipeline

    在应用程序关闭时正确停止Pipeline,以确保释放所有资源。

        pipe.stop();
        if(imuPipeline) {
            imuPipeline->stop();
        }

     

     

    完整代码

    这是一个完整应用程序的代码

    #include "window.hpp"

    #include "libobsensor/hpp/Pipeline.hpp"
    #include "libobsensor/hpp/Error.hpp"
    #include <mutex>
    #include <thread>

    int main(int argc, char **argv) try {
        // Create a pipeline with default device
        ob::Pipeline pipe;

        // Configure which streams to enable or disable for the Pipeline by creating a Config
        std::shared_ptr<ob::Config> config = std::make_shared<ob::Config>();

        // enumerate and config all sensors
        auto device     = pipe.getDevice();
        auto sensorList = device->getSensorList();
        for(int i = 0; i < sensorList->count(); i++) {
            auto sensorType = sensorList->type(i);
            if(sensorType == OB_SENSOR_GYRO || sensorType == OB_SENSOR_ACCEL) {
                continue;
            }
            auto profiles = pipe.getStreamProfileList(sensorType);
            auto profile  = profiles->getProfile(OB_PROFILE_DEFAULT);
            config->enableStream(profile);
        }

        // Start the pipeline with config
        std::mutex                                        frameMutex;
        std::map<OBFrameType, std::shared_ptr<ob::Frame>> frameMap;
        pipe.start(config, [&](std::shared_ptr<ob::FrameSet> frameset) {
            auto count = frameset->frameCount();
            for(int i = 0; i < count; i++) {
                auto                         frame = frameset->getFrame(i);
                std::unique_lock<std::mutex> lk(frameMutex);
                frameMap[frame->type()] = frame;
            }
        });

        // The IMU frame rate is much faster than the video, so it is advisable to use a separate pipeline to obtain IMU data.
        auto                                              dev         = pipe.getDevice();
        auto                                              imuPipeline = std::make_shared<ob::Pipeline>(dev);
        std::mutex                                        imuFrameMutex;
        std::map<OBFrameType, std::shared_ptr<ob::Frame>> imuFrameMap;
        try {
            auto                        accelProfiles = imuPipeline->getStreamProfileList(OB_SENSOR_ACCEL);
            auto                        gyroProfiles  = imuPipeline->getStreamProfileList(OB_SENSOR_GYRO);
            auto                        accelProfile  = accelProfiles->getProfile(OB_PROFILE_DEFAULT);
            auto                        gyroProfile   = gyroProfiles->getProfile(OB_PROFILE_DEFAULT);
            std::shared_ptr<ob::Config> imuConfig     = std::make_shared<ob::Config>();
            imuConfig->enableStream(accelProfile);
            imuConfig->enableStream(gyroProfile);
            imuPipeline->start(imuConfig, [&](std::shared_ptr<ob::FrameSet> frameset) {
                auto count = frameset->frameCount();
                for(int i = 0; i < count; i++) {
                    auto                         frame = frameset->getFrame(i);
                    std::unique_lock<std::mutex> lk(imuFrameMutex);
                    imuFrameMap[frame->type()] = frame;
                }
            });
        }
        catch(...) {
            std::cout << "IMU sensor not found!" << std::endl;
            imuPipeline.reset();
        }

        // Create a window for rendering and set the resolution of the window
        Window app("MultiStream", 1280, 720, RENDER_GRID);
        while(app) {
            std::vector<std::shared_ptr<ob::Frame>> framesForRender;
            {
                std::unique_lock<std::mutex> lock(frameMutex);
                for(auto &frame: frameMap) {
                    framesForRender.push_back(frame.second);
                }
            }
            {
                std::unique_lock<std::mutex> lock(imuFrameMutex);
                for(auto &frame: imuFrameMap) {
                    framesForRender.push_back(frame.second);
                }
            }
            app.addToRender(framesForRender);
        }

        // Stop the Pipeline, no frame data will be generated
        pipe.stop();
        if(imuPipeline) {
            imuPipeline->stop();
        }
        return 0;
    }
    catch(ob::Error &e) {
        std::cerr << "function:" << e.getName() << "\nargs:" << e.getArgs() << "\nmessage:" << e.getMessage() << "\ntype:" << e.getExceptionType() << std::endl;
        exit(EXIT_FAILURE);
    }

     

     

    下一步

     

    -了解如何使用Orbbec SDK配置和使用单个传感器。

    -探索 Orbbec SDK 文档中提供的高级功能和设置。

    -开始将 Orbbec 设备功能集成到您的大型项目和应用程序中。

     

     


    友情链接: