点云提取定量评估,通过与人工提取点云求交集计算错分和漏分

记录一下点云求交集的代码,因为做了一个分割,然后需要计算分割结果的定量评估。

自动提取点云 A

人工提取点云 B

交集点云M

漏分fn= 点云B的数量-交集M的数量

错分fp=点云A的数量-交集M的数量

其实cloudcompare有相同的功能,tools-other-remove duplicate points。但是与代码计算的结果差距十位数的差距,对应点云来说,相差其实不大

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include //写入txt
#include
#include //将整型转换成字符型


using namespace std;  // 可以加入 std 的命名空间

//给定两个点云A和B,求取两个点云的不同之处,A异B表示在A中不在B中的点,B异A表示在B中不在A中的点


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


	//-------------------------------------------------------------------------------
	srand(time(NULL));  //seeds rand() with the system time 
	time_t begin, end;
	begin = clock();  //开始计时
	//-------------------------------------------------------------------------------


	pcl::PointCloud::Ptr Acloud(new pcl::PointCloud);	// 存放A点云
	if (pcl::io::loadPCDFile("D:\\论文实验\\getway\\数据1\\5翻转复原\\getway_1_obb.pcd", *Acloud) == -1)//*打开点云文件。
	{                                                                          
		PCL_ERROR("Couldn't read that boundary pcd file\n");                             
		return(-1);
	}


	pcl::PointCloud::Ptr Bcloud(new pcl::PointCloud);	// 存放B点云
	if (pcl::io::loadPCDFile("D:\\论文实验\\getway\\数据1\\人工提取\\data1_fd1_rengong.pcd", *Bcloud) == -1)//*打开点云文件。
	{                                                                           
		PCL_ERROR("Couldn't read that outlier pcd file\n");                             
		return(-1);
	}


	pcl::KdTreeFLANN kdtree;
	kdtree.setInputCloud(Bcloud);//在Bcloud中进行搜索
	int K = 1;
	std::vector pointIdxNKNSearch(K);//进行1邻域点搜索
	std::vector pointNKNSquaredDistance(K);



	//设置参数
	int nr_Apoints = (int)Acloud->points.size();//获得Acloud的大小,用于计算时的循环
	int nr_Bpoints = (int)Bcloud->points.size();//获得Bcloud的大小,用于计算时的循环

	std::vector LA01(nr_Apoints, 0); //存放各点有无重合点的标记。初始化为0,其中0表示无重合点,1表示有重合点
	std::vector LB01(nr_Bpoints, 0); //存放各点有无重合点的标记。初始化为0,其中0表示无重合点,1表示有重合点

	std::vector LA;  LA.clear();  //存放A中异于B的点,初始为空!!!,不定义长度,因此后面要用L.push_back(i)来压入数据。
	std::vector LB;  LB.clear();  //存放B中异于A的点,初始为空!!!,不定义长度,因此后面要用L.push_back(i)来压入数据。


	int number = 0;

#if defined(_OPENMP)
#pragma omp parallel for
#endif

	for (int i = 0; i < nr_Apoints; ++i)//对A中的每个点与B中点进行比较
	{
		//printf("i=%d,线程%d", i, omp_get_thread_num());
		if (kdtree.nearestKSearch(Acloud->points[i], K, pointIdxNKNSearch, pointNKNSquaredDistance) > 0)
		{
			if (pointNKNSquaredDistance[0] == 0)//如果搜索到的第一个点距为0,那么这个点为重合点(因为用A搜B中的点,不存在包含自身的情况)
			{
				LA01[i] = 1;
				LB01[pointIdxNKNSearch[0]] = 1;
				number = number + 1;
			}
		}

	}

	cout << "A中的点有" << number << "个点和B中相同" << endl;

	//for (int ii = 0; ii < nr_Apoints; ++ii)
	//{
	//	if (LA01[ii] == 0)
	//		LA.push_back(ii);
	//}

	//for (int jj = 0; jj < nr_Bpoints; ++jj)
	//{
	//	if (LB01[jj] == 0)
	//		LB.push_back(jj);
	//}



	pcl::PointCloud::Ptr Arecloud(new pcl::PointCloud);// 创建点云Arecloud存放A中剩余(residual)的点
	pcl::copyPointCloud(*Acloud, LA, *Arecloud);//按照索引复制点云

	pcl::PointCloud::Ptr Brecloud(new pcl::PointCloud);// 创建点云Brecloud存放B中剩余(residual)的点
	pcl::copyPointCloud(*Bcloud, LB, *Brecloud);//按照索引复制点云


	//写入磁盘
	//pcl::io::savePCDFileASCII("111.pcd", *Arecloud); //将点云保存到PCD文件中
	//pcl::io::savePCDFileASCII("222.pcd", *Brecloud); //将点云保存到PCD文件中




	//输出A与B坐标一致的点
	std::vector LAB;  LAB.clear();  //存放AB共同的点,初始为空!!!,不定义长度,因此后面要用L.push_back(i)来压入数据。
	for (int iii = 0; iii < nr_Apoints; ++iii)
	{
		if (LA01[iii] == 1)
			LAB.push_back(iii);
	}
	pcl::PointCloud::Ptr ABrecloud(new pcl::PointCloud);// 创建点云Arecloud存放A中剩余(residual)的点
	pcl::copyPointCloud(*Acloud, LAB, *ABrecloud);//按照索引复制点云
	pcl::io::savePCDFileASCII("点云交集.pcd", *ABrecloud); //将点云保存到PCD文件中


	//--------------------------------------------------------------------------------------------
	end = clock();  //结束计时
	double Times = double(end - begin) / CLOCKS_PER_SEC; //将clock()函数的结果转化为以秒为单位的量
	std::cout << "time: " << Times << "s" << std::endl;

	system("pause");
	return 0;
}

你可能感兴趣的:(PCL点云库(配准和分割),c++)