2015-08-26 72 views
0

我寫了一個小代碼片段,使用PCL將兩個點雲與ICP合併。但是,無論我做什麼,最終的點雲都只包含第一個點雲。一個畫面:The source and target on the left, the product on the right.PCL ICP函數不會添加第二個點雲

#define _CRT_SECURE_NO_DEPRECATE 

#include <pcl/point_types.h> 
#include <pcl/visualization/cloud_viewer.h> 
#include <pcl/registration/icp.h> 
#include <pcl/io/pcd_io.h> 
#include <boost/make_shared.hpp> 
#include "Dot3DReader.h" 


int main(int argc, char** argv) 
{ 

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud1(new pcl::PointCloud<pcl::PointXYZ>); 

if (pcl::io::loadPCDFile<pcl::PointXYZ>("D:/Imerso/PCL PointCloudExampleData/Frame1.pcd", *cloud1) == -1) //* load the file 
{ 
    PCL_ERROR("Couldn't read file Frame1.pcd \n"); 
    return (-1); 
} 

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2(new pcl::PointCloud<pcl::PointXYZ>); 

if (pcl::io::loadPCDFile<pcl::PointXYZ>("D:/Imerso/PCL PointCloudExampleData/Frame2.pcd", *cloud2) == -1) //* load the file 
{ 
    PCL_ERROR("Couldn't read file Frame2.pcd \n"); 
    return (-1); 
} 

std::cout << "Read both files." << std::endl; 

pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp; 
icp.setInputSource(cloud1); 
icp.setInputTarget(cloud2); 

boost::shared_ptr<pcl::PointCloud<pcl::PointXYZ>> Final(new pcl::PointCloud<pcl::PointXYZ>()); 


std::cout << "Starting aligning." << std::endl; 

icp.align(*Final); 

std::cout << "Finished aligning." << std::endl; 
std::cout << "has converged:" << icp.hasConverged() << " score: " << 
    icp.getFitnessScore() << std::endl; 
// CloudViewer を生成 
// (表示は別スレッドで実行される) 
pcl::visualization::CloudViewer viewer("Final cloud Viewer"); 


// CloudViewer で點羣を表示 
viewer.showCloud(Final); 

while (true) { 
    // ESC キーで終了 
    if (GetKeyState(VK_ESCAPE) < 0) { 
     return 0; 
    } 
} 
return 0; 
} 

作爲獎勵,我也想用RGB點時保留點的顏色對齊。我怎樣才能做到這一點?

我的猜測是,它找不到匹配,並簡單地丟棄第二個點雲。

謝謝你的幫助。

回答

2

我不確定我是否愚蠢,或者文檔和示例代碼有誤導性,但我設法弄清楚了這些功能的作用以及如何使用它。

.align()函數僅對源點雲應用轉換,以使其與目標點雲相匹配。它返回的點雲是轉換後的源雲,因此您所要做的就是將其附加到您的全球雲。

示例代碼: boost :: shared_ptr> cloud1,cloud2,GlobalCloud; //將前兩個填入你想要合併的點雲。

pcl::IterativeClosestPoint<pcl::PointXYZRGB, pcl::PointXYZRGB> icp; 
icp.setInputSource(cloud1); //This cloud will be transformed to match 
icp.setInputTarget(cloud2); //this cloud. The result is stored in the cloud provided as input below. 


icp.align(*cloud1); //Overwrite the source cloud with the transformed cloud. 

*GlobalCloud = *cloud1 + *cloud2; //Merge the two now aligned and matched clouds. 

//Do whatever you want with the global cloud. 

我希望這可以幫助別人,讓他們不必忍受閱讀源代碼來解碼發生的事情。 (^ - ^)

只要問是否有什麼你想知道,我會盡力幫助。

+0

它會加快,而不是一個列表座標調整大小的點雲,我的意思是寬度和高度相同的深度圖。在深度圖像的內容。 –

+0

@MartijnvanWezel你的意思是過濾點雲,使原始點雲的稀疏表示,然後匹配它們?然後在原始點雲上使用這種轉換?如果是這樣,那麼是的。通常減少點數可以加快算法的速度。但是,這樣做也會降低結果的質量。如果你有一個非常密集的雲,那麼你可以很容易地刪除點而不會失去任何明顯的準確性,但是你必須小心不要去掉太多。 –

+0

不,我的意思是需要orded正方形而不是一個列表,對於更好的ICP,我目前正在與那 –