使用Xtion Pro和DS325深度相机运行以下代码会产生截然不同的结果。 Xtion Pro完美地显示了彩色点云和RGB,而DS325在图像中有许多黑色模糊区域,使得它无法用于我想要的OpenCV功能(转换为Mat格式后)。
此链接似乎是在将XYZ数据捕获为NaN时。例如,即使指出窗口(使得大部分XYZ数据为NaN),Xtion Pro也会显示完整的RGB精细,而对DS325执行相同操作会使整个RGB图像显示为黑色。
有人能告诉我这是否只是新抓取器代码的不完美之处?或者更固有地链接到不同硬件的映射差异?
运行deepsense查看器应用程序(来自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();
}
答案 0 :(得分:2)
DepthSense
抓取器从驱动程序接收两个流:深度和颜色。它们被合并为带有颜色的单点云,然后返回给最终用户。由于所涉及的两个传感器(红外和彩色相机)具有一定的位移和不同的分辨率(分别为QVGA和VGA),因此流中的深度和彩色像素之间的映射并不是微不足道的。实际上,对于每个深度/颜色帧,相机驱动器另外产生所谓的UV图,其可用于建立对应关系。不幸的是,它无法为无效深度像素设置UV坐标,这使得无法为NaN点找到相应的RGB值。
我建议直接使用DepthSense SDK访问原始RGB图像。