ICP配准同名点对输出

使用PCL库的icp算法对两组点云数据进行配准,并输出两组点云的同名点对信息,由于icp算法流程里,source点云向target点云匹配的过程中,每一次迭代都会为source点云内的每个点在target点云内寻找最近点,因此每次迭代过程都会生成一组同名点对。输出每一次迭代过程中的点对信息,就可以找到原始两组点云内的同名点对。
具体操作:修改icp.hpp文件,文件路径:%PCL安装路径%\include\pcl-1.9\pcl\registration\impl\icp.hpp。在函数pcl::IterativeClosestPoint<PointSource, PointTarget, Scalar>::computeTransformation ( PointCloudSource &output, const Matrix4 &guess)中做如下修改:

if (use_reciprocal_correspondence_)
      correspondence_estimation_->determineReciprocalCorrespondences (*correspondences_, corr_dist_threshold_);
    else
      correspondence_estimation_->determineCorrespondences (*correspondences_, corr_dist_threshold_);

后面添加

	//输出对应点对
	//for(int i=0;i<input_->size();i++)
		//cout << "第"<<i<<"组点对:in source " << correspondences_->at(i).index_query <<" ("<< input_transformed->at(i).x << "," << input_transformed->at(i).y << "," << input_transformed->at(i).z
		//<< "), in target "<<correspondences_->at(i).index_match<<" ("<<target_->at(i).x<<","<< target_->at(i).y<<","<< target_->at(i).z<<")." << endl;
	FILE* pOutFile;
	char* strCorFileName = new char[80];
	sprintf(strCorFileName, "e:\\Livox\\%d.txt", nr_iterations_);
	fopen_s(&pOutFile, strCorFileName, "w");
	for (int i = 0; i<input_->size(); i++)
	{
		fprintf(pOutFile, "%f,",input_transformed->at(correspondences_->at(i).index_query).x);
		fprintf(pOutFile, "%f,",input_transformed->at(correspondences_->at(i).index_query).y);
		fprintf(pOutFile, "%f,",input_transformed->at(correspondences_->at(i).index_query).z);
		fprintf(pOutFile, "%d,",correspondences_->at(i).index_query);
		fprintf(pOutFile, "%f,",target_->at(correspondences_->at(i).index_match).x);
		fprintf(pOutFile, "%f,",target_->at(correspondences_->at(i).index_match).y);
		fprintf(pOutFile, "%f,",target_->at(correspondences_->at(i).index_match).z);
		fprintf(pOutFile, "%d,",correspondences_->at(i).index_match);
		fprintf(pOutFile, "%f,",correspondences_->at(i).distance);
		fprintf(pOutFile, "\n");
	}
	fclose(pOutFile);
	delete[] strCorFileName;
	strCorFileName = NULL;

说明:点对的索引值保存在结构体数组Correspondence_里,两个成员index_query和index_match分别表示source点云中点的索引和target点云中寻找到的与source中对应点欧氏距离最近的点的索引。用这两个索引可以访问点云中的点的具体坐标值。source点云每次迭代后的新坐标值保存在input_transformed里,target点云的坐标保存在Registration类的target_成员里。
可以根据具体需求选择要输出的信息类别和顺序,这里分别输出source和target中对应点的坐标和索引,以及两点间的欧氏距离。
输出原始两组点云之间的同名点对:

//输出最终对应点对
  float fDistance = 0.0;
  FILE* pCorFile;
  char* strCorFileName = new char[80];
  sprintf(strCorFileName, "e:\\Livox\\correspondence.txt");
  fopen_s(&pCorFile, strCorFileName, "w");
  float fDistance = 0.0;
  for (int i = 0; i<input_->size(); i++)
  {
	  fprintf(pCorFile, "%f,", input_->at(correspondences_->at(i).index_query).x);
	  fprintf(pCorFile, "%f,", input_->at(correspondences_->at(i).index_query).y);
	  fprintf(pCorFile, "%f,", input_->at(correspondences_->at(i).index_query).z);
	  fprintf(pCorFile, "%d,", correspondences_->at(i).index_query);
	  fprintf(pCorFile, "%f,", target_->at(correspondences_->at(i).index_match).x);
	  fprintf(pCorFile, "%f,", target_->at(correspondences_->at(i).index_match).y);
	  fprintf(pCorFile, "%f,", target_->at(correspondences_->at(i).index_match).z);
	  fprintf(pCorFile, "%d,", correspondences_->at(i).index_match);
	  fDistance = (input_->at(correspondences_->at(i).index_query).x - target_->at(correspondences_->at(i).index_match).x)*
		  (input_->at(correspondences_->at(i).index_query).x - target_->at(correspondences_->at(i).index_match).x) +
		  (input_->at(correspondences_->at(i).index_query).y - target_->at(correspondences_->at(i).index_match).y)*
		  (input_->at(correspondences_->at(i).index_query).y - target_->at(correspondences_->at(i).index_match).y) +
		  (input_->at(correspondences_->at(i).index_query).z - target_->at(correspondences_->at(i).index_match).z)*
		  (input_->at(correspondences_->at(i).index_query).z - target_->at(correspondences_->at(i).index_match).z);
	  fprintf(pCorFile, "%f", fDistance);
	  fprintf(pCorFile, "\n");
  }
  fclose(pCorFile);
  delete[] strCorFileName;
  strCorFileName = NULL;

这样输出的是把source点云中的每个点都在target点云中寻找对应点作为点对,如果两幅点云并不是绝对重合,这种方法就会输出一些非同名点对的对应点,即在现实世界中,该点出现在在source点云中,却并不出现在target点云中。可以在for循环里添加一个if判断:最后一次迭代得到的对应点对里,点对的欧式距离小于一个阈值时,才输出对应点的信息。
参考:这里

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值