c++ - 点云库 1.8 - DepthSense Grabber 似乎没有为 NaN XYZ 点提供 RGB 数据

标签 c++ computer-vision point-cloud-library openni

在 Xtion Pro 和 DS325 深度相机上运行以下代码会得到截然不同的结果。 Xtion Pro 完美地显示了彩色点云和 RGB,而 DS325 在图像中有许多黑色模糊区域,使其无法用于我想要的 OpenCV 功能(转换为 Mat 形式后)。

此链接似乎是在 XYZ 数据被捕获为 NaN 时出现的。例如,即使指向窗口(这使得大部分 XYZ 数据为 NaN),Xtion Pro 也能很好地显示完整的 RGB,而对 DS325 执行相同操作会使几乎整个 RGB 图像显示为黑色。

有人能告诉我这是否只是新抓取器代码中的一个缺陷?或者更内在地与不同硬件的映射差异有关?

运行 depthsense 查看器应用程序(来自 primesense SDK)确实向我确认了深度和完整 RGB 数据可以同时流式传输,所以有点困惑为什么 RGB 似乎被丢弃了。任何帮助将不胜感激!谢谢。

Windows、VS2013、PCL 1.8

#include <iostream>
#include <mutex>

#include <boost/thread/mutex.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/format.hpp>

#include <pcl/io/pcd_io.h>
#include <pcl/common/time.h>
#include <pcl/console/print.h>
#include <pcl/console/parse.h>
#include <pcl/io/io_exception.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/io/depth_sense_grabber.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/image_viewer.h>

using namespace pcl::console; 
typedef pcl::PointCloud<pcl::PointXYZRGBA> PointCloudT; 

std::mutex cloud_mutex; 

void cloud_cb_(const PointCloudT::ConstPtr& callback_cloud, PointCloudT::Ptr& new_cloud_, 
    bool* new_cloud_available_flag) 
{ 
    cloud_mutex.lock(); 
    *new_cloud_ = *callback_cloud; 
    cloud_mutex.unlock(); 
    *new_cloud_available_flag = true; 
} 

void PointXYZRGBAtoCharArray(pcl::PointCloud<pcl::PointXYZRGBA>::Ptr point_cloud_ptr, unsigned char * Image) 
{ 
        for (int i = 0; i < point_cloud_ptr->height; i++) 
        { 
                for (int j = 0; j < point_cloud_ptr->width; j++) 
                { 
                    Image[(i * point_cloud_ptr->width + j) * 3] = point_cloud_ptr->points.at(i * point_cloud_ptr->width + j).r; 
                    Image[(i * point_cloud_ptr->width + j) * 3 + 1] = point_cloud_ptr->points.at(i * point_cloud_ptr->width + j).g; 
                    Image[(i * point_cloud_ptr->width + j) * 3 + 2] = point_cloud_ptr->points.at(i * point_cloud_ptr->width + j).b; 
                } 
        } 
} 

int main() 
{ 
    boost::mutex new_cloud_mutex_; 
    PointCloudT::Ptr cloud(new PointCloudT); 
    bool new_cloud_available_flag = false; 
    std::string device_id = ""; 
    boost::function<void(const typename PointCloudT::ConstPtr&)> f = boost::bind(&cloud_cb_, _1, cloud, &new_cloud_available_flag); 
    boost::shared_ptr<pcl::Grabber> grabber; 
    try 
    { 
            grabber.reset(new pcl::OpenNIGrabber); 
            cout << "Using OpenNI Device" << endl; 
    } 
    catch (pcl::IOException& e) 
    { 
            grabber.reset(new pcl::DepthSenseGrabber); 
            cout << "Using DepthSense Device" << endl; 
    } 
    grabber->registerCallback(f); 
    grabber->start(); 

    // Image Viewer 
    pcl::visualization::ImageViewer Imageviewer("Image Viewer"); 
    unsigned char* Image = new unsigned char[3*cloud->height*cloud->width]; 
    Imageviewer.addRGBImage(Image, cloud->width, cloud->height); 

    // Point Cloud Viewer: 
    pcl::visualization::PCLVisualizer viewer("PCL Viewer"); 
    viewer.setCameraPosition(0, 0, -2, 0, -1, 0, 0); 

    for (;;) 
    { 
            if (new_cloud_available_flag) 
            { 
                    new_cloud_available_flag = false; 
                    cloud_mutex.lock(); 

                    // Update Image 
                    Imageviewer.removeLayer("rgb_image"); 
                    PointXYZRGBAtoCharArray(cloud, Image); 
                    Imageviewer.addRGBImage(Image,cloud->width,cloud->height); 
                    Imageviewer.spinOnce(); 

                    // Update Point Cloud 
                    viewer.removeAllPointClouds(); 
                    viewer.addPointCloud<pcl::PointXYZRGBA>(cloud); 
                    cloud_mutex.unlock(); 
                    viewer.spinOnce(); 
            } 
    } 
    grabber->stop(); 

最佳答案

DepthSense 采集器从驱动程序接收两个流:深度和颜色。它们被合并成一个带有颜色的点云,然后返回给最终用户。由于所涉及的两个传感器(红外和彩色相机)具有一定的位移和不同的分辨率(分别为 QVGA 和 VGA),因此流中深度和彩色像素之间的映射并不简单。事实上,对于每个深度/颜色帧,相机驱动程序额外生成所谓的 UV 映射,可用于建立对应关系。不幸的是,它无法为无效的深度像素设置 UV 坐标,这使得无法为 NaN 点找到对应的 RGB 值。

我建议直接使用 DepthSense SDK 访问原始 RGB 图像。

关于c++ - 点云库 1.8 - DepthSense Grabber 似乎没有为 NaN XYZ 点提供 RGB 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33727575/

相关文章:

c++ - 在 PCL 可视化器中打印选定点的 3D 坐标

C++ "Could not convert ' 类实例'从 'Class (*)()' 到 'Class' ”

python - OpenCV Python - 替换图像中的 channel

C++ VS 调试器转移行为?

matrix - 点相对于引用坐标系的坐标

c++ - 根据标记点对齐 2 张人脸图像

c++ - PCL Release Build 因分配失败而崩溃

c++ - 在类的不同实例的不同线程中使用 "pcl::visualization"

c++ - 在多线程环境中使用 MPI_THREAD_SERIALIZED 时,所有 MPI 调用都需要锁吗?

gcc 4.4.7 : base class subobject padding occupied in derived class object 的 C++ 对象模型