PCL OpenNI2Grabber 在没有查看器的情况下获取点云

PCL OpenNI2Grabber get Point Cloud without viewer

我有一台华硕 XTION 相机。在我的电脑上安装了 Windows 7 和 Visual Studio 2013。我还得到了 PCL,为 VS2013 编译的 openCV,并安装了 openNi 驱动程序。现在我想从相机中获取点云。通过示例,我可以查看实际帧并保存一个:

    // Original code by Geoffrey Biggs, taken from the PCL tutorial in
    // http://pointclouds.org/documentation/tutorials/pcl_visualizer.php

    // Simple OpenNI viewer that also allows to write the current scene to a .pcd
    // when pressing SPACE.
    #define _CRT_SERCURE_NO_WARNINGS
    #include <pcl/io/openni2_grabber.h>
    #include <pcl/io/pcd_io.h>
    #include <pcl/visualization/cloud_viewer.h>
    #include <pcl/console/parse.h>
    #include <pcl/filters/passthrough.h>

    #include <iostream>

    using namespace std;
    using namespace pcl;

    PointCloud<PointXYZRGBA>::Ptr cloudptr(new PointCloud<PointXYZRGBA>); // A cloud that will store color info.
    PointCloud<PointXYZ>::Ptr fallbackCloud(new PointCloud<PointXYZ>); // A fallback cloud with just depth data.
    PointCloud<PointXYZRGBA>::Ptr filteredCloud(new PointCloud<PointXYZRGBA>);
    boost::shared_ptr<visualization::CloudViewer> viewer;                 // Point cloud viewer object.
    Grabber* openniGrabber;                                               // OpenNI grabber that takes data from the device.
    unsigned int filesSaved = 0;                                          // For the numbering of the clouds saved to disk.
    bool saveCloud(false), noColor(false);                                // Program control.

    void
    printUsage(const char* programName)
    {
        cout << "Usage: " << programName << " [options]"
            << endl
            << endl
            << "Options:\n"
            << endl
            << "\t<none>     start capturing from an OpenNI device.\n"
            << "\t-v FILE    visualize the given .pcd file.\n"
            << "\t-h         shows this help.\n";
    }

    // This function is called every time the device has new data.
    void
    grabberCallback(const PointCloud<PointXYZRGBA>::ConstPtr& cloud)
    {
        if (!viewer->wasStopped())
            viewer->showCloud(cloud);

        if (saveCloud)
        {
            stringstream stream;
            stream << "inputCloud" << filesSaved << ".pcd";
            string filename = stream.str();

            // Filter object.
            PassThrough<pcl::PointXYZRGBA> filter;
            filter.setInputCloud(cloud);
            // Filter out all points with Z values not in the [0-2] range.
            filter.setFilterFieldName("z");
            filter.setFilterLimits(0.0, 1.5);

            filter.filter(*filteredCloud);

            if (io::savePCDFile(filename, *filteredCloud, true) == 0)
            {
                filesSaved++;
                cout << "Saved " << filename << "." << endl;
            }
            else PCL_ERROR("Problem saving %s.\n", filename.c_str());

            saveCloud = false;
        }
    }

    // For detecting when SPACE is pressed.
    void
    keyboardEventOccurred(const visualization::KeyboardEvent& event,
    void* nothing)
    {
        if (event.getKeySym() == "space" && event.keyDown())
            saveCloud = true;
    }

    // Creates, initializes and returns a new viewer.
    boost::shared_ptr<visualization::CloudViewer>
    createViewer()
    {
        boost::shared_ptr<visualization::CloudViewer> v
            (new visualization::CloudViewer("OpenNI viewer"));
        v->registerKeyboardCallback(keyboardEventOccurred);

        return (v);
    }

    int
    main(int argc, char** argv)
    {
        if (console::find_argument(argc, argv, "-h") >= 0)
        {
            printUsage(argv[0]);
            return -1;
        }

        bool justVisualize(false);
        string filename;
        if (console::find_argument(argc, argv, "-v") >= 0)
        {
            if (argc != 3)
            {
                printUsage(argv[0]);
                return -1;
            }

            filename = argv[2];
            justVisualize = true;
        }
        else if (argc != 1)
        {
            printUsage(argv[0]);
            return -1;
        }

        // First mode, open and show a cloud from disk.
        if (justVisualize)
        {
            // Try with color information...
            try
            {
                io::loadPCDFile<PointXYZRGBA>(filename.c_str(), *cloudptr);
            }
            catch (PCLException e1)
            {
                try
                {
                    // ...and if it fails, fall back to just depth.
                    io::loadPCDFile<PointXYZ>(filename.c_str(), *fallbackCloud);
                }
                catch (PCLException e2)
                {
                    return -1;
                }

                noColor = true;
            }

            cout << "Loaded " << filename << "." << endl;
            if (noColor)
                cout << "This cloud has no RGBA color information present." << endl;
            else cout << "This cloud has RGBA color information present." << endl;
        }
        // Second mode, start fetching and displaying frames from the device.
        else
        {
            openniGrabber = new pcl::io::OpenNI2Grabber();
            if (openniGrabber == 0)
                return -1;
            boost::function<void(const PointCloud<PointXYZRGBA>::ConstPtr&)> f =
                boost::bind(&grabberCallback, _1);
            openniGrabber->registerCallback(f);
        }

        viewer = createViewer();

        if (justVisualize)
        {
            if (noColor)
                viewer->showCloud(fallbackCloud);
            else viewer->showCloud(cloudptr);
        }
        else openniGrabber->start();

        // Main loop.
        while (!viewer->wasStopped())
            boost::this_thread::sleep(boost::posix_time::seconds(1));

        if (!justVisualize)
            openniGrabber->stop();
    }

但是有了这段代码,我需要查看器。如何在没有查看器的情况下获取点云?它应该在没有 kinect SDK 的情况下工作,只有 PCL、openni.

我是这样解决问题的:

    #include <pcl/io/openni2_grabber.h>
    #include <pcl/io/pcd_io.h>
    #include <pcl/console/parse.h>
    #include <iostream>

    using namespace std;
    using namespace pcl;

    int main(int argc, char** argv)
    {
        PointCloud<PointXYZRGBA>::Ptr sourceCloud(new PointCloud<PointXYZRGBA>);

        boost::function<void(const PointCloud<PointXYZRGBA>::ConstPtr&)> function = [&sourceCloud](const PointCloud<PointXYZRGBA>::ConstPtr &cloud)
        {
            copyPointCloud(*cloud, *sourceCloud);
        };

        // Create Kinect2Grabber
        Grabber* grabber = new io::OpenNI2Grabber();
        // Regist Callback Function
        grabber->registerCallback(function);
        // Start Retrieve Data
        grabber->start();
        boost::this_thread::sleep(boost::posix_time::seconds(1));
        // Stop Retrieve Data
        grabber->stop();
        cout << "The Cloud size: " << sourceCloud->size() << " points ..." << endl;
    }