2012-07-23 91 views
2

在Ubuntu上使用點雲庫,我試圖從Kinect中取多個點雲並將它們存儲在內存中供以後在程序中使用。我在這篇文章底部顯示的代碼旨在存儲來自Kinect的第一個點雲並輸出其寬度和高度。該計劃給了我一個運行時錯誤:使用點雲庫來存儲來自Kinect的點雲

/usr/include/boost/smart_ptr/shared_ptr.hpp:418: T* boost::shared_ptr<T>::operator->() const [with T = pcl::PointCloud<pcl::PointXYZ>]: Assertion `px != 0' failed. 

所有幫助是極大的讚賞,我總是接受一個答案!

代碼:

#include <pcl/io/openni_grabber.h> 
    #include <pcl/visualization/cloud_viewer.h> 

class SimpleOpenNIViewer 
{ 
    public: 
    SimpleOpenNIViewer() : viewer ("PCL OpenNI Viewer") {} 

pcl::PointCloud<pcl::PointXYZ>::Ptr prevCloud; 


    void cloud_cb_ (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud) 
    { 


if (!viewer.wasStopped()) 
    viewer.showCloud (cloud); 


//ICP start 
if(!prevCloud) { 
    pcl::PointCloud<pcl::PointXYZ>::Ptr prevCloud(new pcl::PointCloud<pcl::PointXYZ>()); 

    pcl::copyPointCloud<pcl::PointXYZ, pcl::PointXYZ>(*cloud, *prevCloud); 
} 

cout << prevCloud->width << " by " << prevCloud->height << endl; 



    } 

    void run() 
    { 
    pcl::Grabber* interface = new pcl::OpenNIGrabber(); 

    boost::function<void (const pcl::PointCloud<pcl::PointXYZ>::ConstPtr&)> f = 
     boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1); 


    interface->registerCallback (f); 

    interface->start(); 


    while (!viewer.wasStopped()) 
    { 
     boost::this_thread::sleep (boost::posix_time::seconds (1)); 
    } 

    interface->stop(); 
    } 

    pcl::visualization::CloudViewer viewer; 
}; 

    int main() 
{ 
SimpleOpenNIViewer v; 
v.run(); 
return 0; 
} 

回答

2

試試這個,我沒有安裝Kinect驅動,所以我無法測試。基本上在我的版本prevCloud是在構造函數中實例化的,因此(!prevCloud)將始終等於'false'。也就是說prevCloud.get() != NULL

#include <pcl/io/openni_grabber.h> 
#include <pcl/visualization/cloud_viewer.h> 

class SimpleOpenNIViewer 
{ 
typedef pcl::PointXYZ       Point; 
typedef pcl::PointCloud<Point>     PointCloud; 
public: 
SimpleOpenNIViewer() : viewer ("PCL OpenNI Viewer") { 
     prevCloud = PointCloud::Ptr(NULL); 
    } 

void cloud_cb_ (const PointCloud::ConstPtr &cloud) 
{ 
    if (!viewer.wasStopped()) 
     viewer.showCloud (cloud); 
      if (!prevCloud) // init previous cloud if first frame 
        prevCloud = PointCloud::Ptr(new PointCloud); 
      else. // else RunICP between cloud and prevCloud 
        //RunICP(cloud,prevCloud); 

      //Copy new frame in to prevCloud 
    pcl::copyPointCloud<Point, Point>(*cloud, *prevCloud); 
    cout << prevCloud->width << " by " << prevCloud->height << endl; 
} 

void run() 
{ 
    pcl::Grabber* interface = new pcl::OpenNIGrabber(); 

    boost::function<void (const PointCloud::ConstPtr&)> f = 
    boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1); 

    interface->registerCallback (f); 
    interface->start(); 


    while (!viewer.wasStopped()) 
    { 
     boost::this_thread::sleep (boost::posix_time::seconds (1)); 
    } 

    interface->stop(); 
} 

PointCloud::Ptr prevCloud; 
pcl::visualization::CloudViewer viewer; 
}; 

int main() 
{ 
SimpleOpenNIViewer v; 
v.run(); 
return 0; 
} 
+0

我得到一系列640x480的,所以這似乎做它應該做的。但是,我試圖在if(!prevCloud)塊中封裝copyPointCloud語句,但後來我得到了一系列0x0。任何想法爲什麼? – danielmhanover 2012-07-26 02:18:56

+0

http://stackoverflow.com/questions/7226801/how-does-shared-ptr-work-in-if-condition可能會有所幫助。基本上在我的版本prevCloud是在構造函數中實例化的,所以(!prevCloud)將永遠等於'false'。也就是說prevCloud.get()!= NULL。 – Jerdak 2012-07-26 02:57:35

+0

我想出了一個臨時解決方案:if(prevCloud-> width == 0),但這顯然更像是一種解決方法。你知道更具體的解決方案嗎? – danielmhanover 2012-07-26 03:28:02

0

你正在創建一個新的局部變量prevCloud,並複製到cloud它,而不是複製到prevCloud領域。因此,如果該字段的值在if {}之前爲空,則它在if {}之後仍然爲空,因此當您嘗試對其進行解引用時會引發錯誤。

+0

你能解釋一下嗎?我不太明白你的意思。 – danielmhanover 2012-07-23 02:40:00

+0

在'cloud_cb_'之前定義'prevCloud'之前,您會在'cloud_cb_'中第二次定義它。 – Jerdak 2012-07-23 03:36:00

+0

哦,我明白了。但是如果我刪除cloud_cb_中的定義,我仍然會得到相同的斷言錯誤。我如何使prevCloud變量全局並避免雙重定義? – danielmhanover 2012-07-23 03:59:33

0

可能是這樣的代碼可以幫助你,雲被保存在「PCD」文件,看看here

而另一種選擇是用「Kinfu」項目工作從PCL