Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile "Sample-PointCloud" in Visual Studio #144

Open
triplecmike opened this issue Oct 23, 2024 · 2 comments
Open

Compile "Sample-PointCloud" in Visual Studio #144

triplecmike opened this issue Oct 23, 2024 · 2 comments

Comments

@triplecmike
Copy link

Hi,

I'm new to this device and C++ and have a quite basic question. I was trying to compile and run the sample program Sample-PointCloud in Visual Studio.
I've added directories through Project -> Properties:
VC++ Directories

C:\OrbbecSDK_v1.10.12\SDK\include
C:\OrbbecSDK_v1.10.12\SDK\lib

Linker -> Input

OrbbecSDK.lib

image
Many errors popped out when I tried debugging and built the project:

Severity	Code	Description	Project	File	Line	Suppression State	Details
Error (active)	E0020	identifier "kbhit" is undefined	PointCloudTest	C:\Users\mchang\source\repos\PointCloudTest\PointCloudTest\Source.cpp	152		
Error (active)	E0020	identifier "getch" is undefined	PointCloudTest	C:\Users\mchang\source\repos\PointCloudTest\PointCloudTest\Source.cpp	153		
Warning	C4251	'ob::Context::impl_': 'std::unique_ptr<ContextImpl,std::default_delete<ContextImpl>>' needs to have dll-interface to be used by clients of 'ob::Context'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Context.hpp	23		
Warning	C4251	'std::enable_shared_from_this<ob::Filter>::_Wptr': 'std::weak_ptr<_Ty>' needs to have dll-interface to be used by clients of 'std::enable_shared_from_this<ob::Filter>'
        with
        [
            _Ty=ob::Filter
        ]	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Filter.hpp	27		
Warning	C4251	'ob::Filter::impl_': 'std::shared_ptr<FilterImpl>' needs to have dll-interface to be used by clients of 'ob::Filter'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Filter.hpp	103		
Warning	C4251	'ob::Filter::type_': 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' needs to have dll-interface to be used by clients of 'ob::Filter'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Filter.hpp	104		
Warning	C4251	'ob::Device::impl_': 'std::unique_ptr<DeviceImpl,std::default_delete<DeviceImpl>>' needs to have dll-interface to be used by clients of 'ob::Device'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Device.hpp	31		
Warning	C4251	'ob::DeviceInfo::impl_': 'std::unique_ptr<DeviceInfoImpl,std::default_delete<DeviceInfoImpl>>' needs to have dll-interface to be used by clients of 'ob::DeviceInfo'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Device.hpp	642		
Warning	C4251	'ob::DeviceList::impl_': 'std::unique_ptr<DeviceListImpl,std::default_delete<DeviceListImpl>>' needs to have dll-interface to be used by clients of 'ob::DeviceList'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Device.hpp	759		
Warning	C4251	'ob::CameraParamList::impl_': 'std::unique_ptr<CameraParamListImpl,std::default_delete<CameraParamListImpl>>' needs to have dll-interface to be used by clients of 'ob::CameraParamList'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Device.hpp	869		
Warning	C4251	'ob::OBDepthWorkModeList::impl_': 'std::unique_ptr<OBDepthWorkModeListImpl,std::default_delete<OBDepthWorkModeListImpl>>' needs to have dll-interface to be used by clients of 'ob::OBDepthWorkModeList'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Device.hpp	896		
Warning	C4251	'ob::DevicePresetList::impl_': 'std::unique_ptr<DevicePresetListImpl,std::default_delete<DevicePresetListImpl>>' needs to have dll-interface to be used by clients of 'ob::DevicePresetList'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Device.hpp	940		
Warning	C4251	'ob::Error::impl_': 'std::unique_ptr<ErrorImpl,std::default_delete<ErrorImpl>>' needs to have dll-interface to be used by clients of 'ob::Error'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Error.hpp	16		
Warning	C4251	'std::enable_shared_from_this<ob::Frame>::_Wptr': 'std::weak_ptr<_Ty>' needs to have dll-interface to be used by clients of 'std::enable_shared_from_this<ob::Frame>'
        with
        [
            _Ty=ob::Frame
        ]	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Frame.hpp	42		
Warning	C4251	'ob::Frame::impl_': 'std::unique_ptr<FrameImpl,std::default_delete<FrameImpl>>' needs to have dll-interface to be used by clients of 'ob::Frame'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Frame.hpp	44		
Warning	C4251	'ob::Pipeline::impl_': 'std::unique_ptr<PipelineImpl,std::default_delete<PipelineImpl>>' needs to have dll-interface to be used by clients of 'ob::Pipeline'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Pipeline.hpp	30		
Warning	C4251	'ob::Config::impl_': 'std::unique_ptr<ConfigImpl,std::default_delete<ConfigImpl>>' needs to have dll-interface to be used by clients of 'ob::Config'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Pipeline.hpp	212		
Warning	C4251	'ob::Recorder::impl_': 'std::unique_ptr<RecorderImpl,std::default_delete<RecorderImpl>>' needs to have dll-interface to be used by clients of 'ob::Recorder'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\RecordPlayback.hpp	25		
Warning	C4251	'ob::Playback::impl_': 'std::unique_ptr<PlaybackImpl,std::default_delete<PlaybackImpl>>' needs to have dll-interface to be used by clients of 'ob::Playback'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\RecordPlayback.hpp	65		
Warning	C4251	'ob::Sensor::impl_': 'std::unique_ptr<SensorImpl,std::default_delete<SensorImpl>>' needs to have dll-interface to be used by clients of 'ob::Sensor'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Sensor.hpp	33		
Warning	C4251	'ob::SensorList::impl_': 'std::unique_ptr<SensorListImpl,std::default_delete<SensorListImpl>>' needs to have dll-interface to be used by clients of 'ob::SensorList'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Sensor.hpp	82		
Warning	C4251	'ob::OBFilterList::impl_': 'std::unique_ptr<OBFilterListImpl,std::default_delete<OBFilterListImpl>>' needs to have dll-interface to be used by clients of 'ob::OBFilterList'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\Sensor.hpp	127		
Warning	C4251	'std::enable_shared_from_this<ob::StreamProfile>::_Wptr': 'std::weak_ptr<_Ty>' needs to have dll-interface to be used by clients of 'std::enable_shared_from_this<ob::StreamProfile>'
        with
        [
            _Ty=ob::StreamProfile
        ]	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\StreamProfile.hpp	22		
Warning	C4251	'ob::StreamProfile::impl_': 'std::unique_ptr<StreamProfileImpl,std::default_delete<StreamProfileImpl>>' needs to have dll-interface to be used by clients of 'ob::StreamProfile'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\StreamProfile.hpp	24		
Warning	C4251	'ob::StreamProfileList::impl_': 'std::unique_ptr<StreamProfileListImpl,std::default_delete<StreamProfileListImpl>>' needs to have dll-interface to be used by clients of 'ob::StreamProfileList'	PointCloudTest	C:\OrbbecSDK_v1.10.12\SDK\include\libobsensor\hpp\StreamProfile.hpp	214		
Error	C4996	'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.	PointCloudTest	C:\Users\mchang\source\repos\PointCloudTest\PointCloudTest\Source.cpp	15		
Error	C4996	'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.	PointCloudTest	C:\Users\mchang\source\repos\PointCloudTest\PointCloudTest\Source.cpp	37		
Error	C3861	'kbhit': identifier not found	PointCloudTest	C:\Users\mchang\source\repos\PointCloudTest\PointCloudTest\Source.cpp	152		
Error	C3861	'getch': identifier not found	PointCloudTest	C:\Users\mchang\source\repos\PointCloudTest\PointCloudTest\Source.cpp	153		

And here's the original code in the sample folder:

#include "libobsensor/ObSensor.hpp"
// #include "opencv2/opencv.hpp"
#include <fstream>
#include <iostream>
// #include "utils.hpp"
#include "libobsensor/hpp/Utils.hpp"

#define KEY_ESC 27
#define KEY_R 82
#define KEY_r 114

// Save point cloud data to ply
void savePointsToPly(std::shared_ptr<ob::Frame> frame, std::string fileName) {
    int   pointsSize = frame->dataSize() / sizeof(OBPoint);
    FILE* fp = fopen(fileName.c_str(), "wb+");
    fprintf(fp, "ply\n");
    fprintf(fp, "format ascii 1.0\n");
    fprintf(fp, "element vertex %d\n", pointsSize);
    fprintf(fp, "property float x\n");
    fprintf(fp, "property float y\n");
    fprintf(fp, "property float z\n");
    fprintf(fp, "end_header\n");

    OBPoint* point = (OBPoint*)frame->data();
    for (int i = 0; i < pointsSize; i++) {
        fprintf(fp, "%.3f %.3f %.3f\n", point->x, point->y, point->z);
        point++;
    }

    fflush(fp);
    fclose(fp);
}

// Save colored point cloud data to ply
void saveRGBPointsToPly(std::shared_ptr<ob::Frame> frame, std::string fileName) {
    int   pointsSize = frame->dataSize() / sizeof(OBColorPoint);
    FILE* fp = fopen(fileName.c_str(), "wb+");
    fprintf(fp, "ply\n");
    fprintf(fp, "format ascii 1.0\n");
    fprintf(fp, "element vertex %d\n", pointsSize);
    fprintf(fp, "property float x\n");
    fprintf(fp, "property float y\n");
    fprintf(fp, "property float z\n");
    fprintf(fp, "property uchar red\n");
    fprintf(fp, "property uchar green\n");
    fprintf(fp, "property uchar blue\n");
    fprintf(fp, "end_header\n");

    OBColorPoint* point = (OBColorPoint*)frame->data();
    for (int i = 0; i < pointsSize; i++) {
        fprintf(fp, "%.3f %.3f %.3f %d %d %d\n", point->x, point->y, point->z, (int)point->r, (int)point->g, (int)point->b);
        point++;
    }

    fflush(fp);
    fclose(fp);
}

int main(int argc, char** argv) try {
    ob::Context::setLoggerSeverity(OB_LOG_SEVERITY_WARN);
    // create pipeline
    ob::Pipeline pipeline;

    // 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>();

    // Turn on D2C alignment, which needs to be turned on when generating RGBD point clouds

    std::shared_ptr<ob::VideoStreamProfile> colorProfile = nullptr;
    try {
        // Get all stream profiles of the color camera, including stream resolution, frame rate, and frame format
        auto colorProfiles = pipeline.getStreamProfileList(OB_SENSOR_COLOR);
        if (colorProfiles) {
            auto profile = colorProfiles->getProfile(OB_PROFILE_DEFAULT);
            colorProfile = profile->as<ob::VideoStreamProfile>();
        }
        config->enableStream(colorProfile);
    }
    catch (ob::Error& e) {
        config->setAlignMode(ALIGN_DISABLE);
        std::cerr << "Current device is not support color sensor!" << std::endl;
    }

    // Get all stream profiles of the depth camera, including stream resolution, frame rate, and frame format
    std::shared_ptr<ob::StreamProfileList> depthProfileList;
    OBAlignMode                            alignMode = ALIGN_DISABLE;
    if (colorProfile) {
        // Try find supported depth to color align hardware mode profile
        depthProfileList = pipeline.getD2CDepthProfileList(colorProfile, ALIGN_D2C_HW_MODE);
        if (depthProfileList->count() > 0) {
            alignMode = ALIGN_D2C_HW_MODE;
        }
        else {
            // Try find supported depth to color align software mode profile
            depthProfileList = pipeline.getD2CDepthProfileList(colorProfile, ALIGN_D2C_SW_MODE);
            if (depthProfileList->count() > 0) {
                alignMode = ALIGN_D2C_SW_MODE;
            }
        }

        try {
            // Enable frame synchronization
            pipeline.enableFrameSync();
        }
        catch (ob::Error& e) {
            std::cerr << "Current device is not support frame sync!" << std::endl;
        }
    }
    else {
        depthProfileList = pipeline.getStreamProfileList(OB_SENSOR_DEPTH);
    }

    if (depthProfileList->count() > 0) {
        std::shared_ptr<ob::StreamProfile> depthProfile;
        try {
            // Select the profile with the same frame rate as color.
            if (colorProfile) {
                depthProfile = depthProfileList->getVideoStreamProfile(OB_WIDTH_ANY, OB_HEIGHT_ANY, OB_FORMAT_ANY, colorProfile->fps());
            }
        }
        catch (...) {
            depthProfile = nullptr;
        }

        if (!depthProfile) {
            // If no matching profile is found, select the default profile.
            depthProfile = depthProfileList->getProfile(OB_PROFILE_DEFAULT);
        }
        config->enableStream(depthProfile);
    }
    config->setAlignMode(alignMode);

    // start pipeline with config
    pipeline.start(config);

    // Create a point cloud Filter object (the device parameters will be obtained inside the Pipeline when the point cloud filter is created, so try to
    // configure the device before creating the filter)
    ob::PointCloudFilter pointCloud;

    // get camera intrinsic and extrinsic parameters form pipeline and set to point cloud filter
    auto cameraParam = pipeline.getCameraParam();
    pointCloud.setCameraParam(cameraParam);

    // operation prompt
    std::cout << "Press R or r to create RGBD PointCloud and save to ply file! " << std::endl;
    std::cout << "Press D or d to create Depth PointCloud and save to ply file! " << std::endl;
    std::cout << "Press ESC to exit! " << std::endl;

    int count = 0;
    while (true) {
        auto frameset = pipeline.waitForFrames(100);
        if (kbhit()) {
            int key = getch();
            // Press the ESC key to exit
            if (key == KEY_ESC) {
                break;
            }
            if (key == 'R' || key == 'r') {
                count = 0;
                // Limit up to 10 repetitions
                while (count++ < 10) {
                    // Wait for a frame of data, the timeout is 100ms
                    auto frameset = pipeline.waitForFrames(100);
                    if (frameset != nullptr && frameset->depthFrame() != nullptr && frameset->colorFrame() != nullptr) {
                        // point position value multiply depth value scale to convert uint to millimeter (for some devices, the default depth value uint is not
                        // millimeter)
                        auto depthValueScale = frameset->depthFrame()->getValueScale();
                        pointCloud.setPositionDataScaled(depthValueScale);
                        try {
                            // Generate a colored point cloud and save it
                            std::cout << "Save RGBD PointCloud ply file..." << std::endl;
                            pointCloud.setCreatePointFormat(OB_FORMAT_RGB_POINT);
                            std::shared_ptr<ob::Frame> frame = pointCloud.process(frameset);
                            saveRGBPointsToPly(frame, "RGBPoints.ply");
                            std::cout << "RGBPoints.ply Saved" << std::endl;
                        }
                        catch (std::exception& e) {
                            std::cout << "Get point cloud failed" << std::endl;
                        }
                        break;
                    }
                    else {
                        std::cout << "Get color frame or depth frame failed!" << std::endl;
                    }
                }
            }
            else if (key == 'D' || key == 'd') {
                count = 0;
                // Limit up to 10 repetitions
                while (count++ < 10) {
                    // Wait for up to 100ms for a frameset in blocking mode.
                    auto frameset = pipeline.waitForFrames(100);
                    if (frameset != nullptr && frameset->depthFrame() != nullptr) {
                        // point position value multiply depth value scale to convert uint to millimeter (for some devices, the default depth value uint is not
                        // millimeter)
                        auto depthValueScale = frameset->depthFrame()->getValueScale();
                        pointCloud.setPositionDataScaled(depthValueScale);
                        try {
                            // generate point cloud and save
                            std::cout << "Save Depth PointCloud to ply file..." << std::endl;
                            pointCloud.setCreatePointFormat(OB_FORMAT_POINT);
                            std::shared_ptr<ob::Frame> frame = pointCloud.process(frameset);
                            savePointsToPly(frame, "DepthPoints.ply");
                            std::cout << "DepthPoints.ply Saved" << std::endl;
                        }
                        catch (std::exception& e) {
                            std::cout << "Get point cloud failed" << std::endl;
                        }
                        break;
                    }
                }
            }
        }
    }
    // stop the pipeline
    pipeline.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);
}

Could anyone help me with this? Thank you very much!

@zhonghong322
Copy link
Contributor

You can refer to this document to compile the sample. https://github.com/orbbec/OrbbecSDK/blob/main/doc/tutorial/English/Environment_Configuration.md

@triplecmike
Copy link
Author

Thank you so much. this is very helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants