点云旋转处理

实现代码为:

//以中心化点进行旋转
	double theta = atan(maindirection.a);//计算的是弧度单位
	for (int i = 0; i < origipts.size(); i++)
	{
		pcl::PointXYZ tempone;
		tempone.x = aftercenerlizepts[i].x*cos(theta) + aftercenerlizepts[i].y*sin(theta) + center.x;
		tempone.y = aftercenerlizepts[i].y*cos(theta) - aftercenerlizepts[i].x*sin(theta) + center.y;
		transpts.push_back(tempone);
	}

3、测试结果

本程序是在PCL环境下运行,测试工程需要先配置好PCL环境,将点云旋转_test.cpp添加到源文件中即可运行。

3.1 轮廓点检测结果

轮廓点提取主函数如下:

//(1)测试边缘点提取结果
void main()
{
	char *filepath = "D:\\testdata\\points.xyz";
	char *savepath = "D:\\testdata\\points_boundpts.xyz";

	vector<pcl::PointXYZ> origipts = ReadPointXYZIntoVector(filepath);
	//假设其z坐标都为0,为平面坐标
	for (int i = 0; i < origipts.size(); i++)
	{
		origipts[i].z = 0;
	}
	
	vector<pcl::PointXYZ> boundpts, nonbounpts;
	double r = 0.8;
	Bounpts(origipts, r, boundpts, nonbounpts);



	ofstream outfile(savepath, ios::out);
	for (int j = 0; j < boundpts.size(); j++)
	{
		outfile << fixed << setprecision(3) << boundpts[j].x << " " << boundpts[j].y << " " << boundpts[j].z << " " << fixed << setprecision(0) << 255 << " " << 0 << " " << 0 << endl;
	}
	for (int j = 0; j < nonbounpts.size(); j++)
	{
		outfile << fixed << setprecision(3) << nonbounpts[j].x << " " << nonbounpts[j].y << " " << nonbounpts[j].z << " " << fixed << setprecision(0) << 255 << " " << 255 << " " << 255 << endl;
	}
	outfile.close();
	cout << "结束" << endl;
	pcl::visualization::PCLVisualizer viewer("点云可视化");
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr new_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
	new_cloud->width = origipts.size();
	new_cloud->height = 1;
	new_cloud->is_dense = false;
	new_cloud->points.resize(new_cloud->width*new_cloud->height);


	for (int i = 0; i < origipts.size(); i++)
	{
		if (i < boundpts.size())
		{
			new_cloud->points[i].x = boundpts[i].x;
			new_cloud->points[i].y = boundpts[i].y;
			new_cloud->points[i].z = boundpts[i].z;
			new_cloud->points[i].r = 255;
			new_cloud->points[i].g = 0;
			new_cloud->points[i].b = 0;
		}
		else
		{
			new_cloud->points[i].x = nonbounpts[i - boundpts.size()].x;
			new_cloud->points[i].y = nonbounpts[i - boundpts.size()].y;
			new_cloud->points[i].z = nonbounpts[i - boundpts.size()].z;
			new_cloud->points[i].r = 255;
			new_cloud->points[i].g = 255;
			new_cloud->points[i].b = 255;
		}
	}

	pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB>fildColor(new_cloud);
	viewer.setBackgroundColor(0, 0, 0);
	viewer.addPointCloud<pcl::PointXYZRGB>(new_cloud, fildColor, "inCloud");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "inCloud");
	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}

	system("pause");

}

红色点为边缘点,可以看到边缘提取效果比较理想。

3.2 轮廓点分组

轮廓点分组测试结果如下:

//(2)测试边缘点分组
void main()
{
	char *filepath = "D:\\testdata\\points.xyz";
	char *savepath = "D:\\testdata\\points_boundpts_group.xyz";

	vector<pcl::PointXYZ> origipts = ReadPointXYZIntoVector(filepath);
	//假设其z坐标都为0,为平面坐标
	for (int i = 0; i < origipts.size(); i++)
	{
		origipts[i].z = 0;
	}

	vector<pcl::PointXYZ> boundpts, nonbounpts;
	double r = 0.8;
	Bounpts(origipts, r, boundpts, nonbounpts);

	vector<vector<pcl::PointXYZ>> multi_linepoints;
	double ds_thres = 0.35;
	double linefit_knn = 5;
	double growing_knn = 5;
	GroupPts(boundpts, ds_thres, linefit_knn, growing_knn, multi_linepoints);
	srand((int)time(0));
	ofstream outfile(savepath, ios::out);
	for (int i = 0; i < multi_linepoints.size(); i++)
	{
		double R = rand() % 255;
		double G = rand() % 255;
		double B = rand() % 255;
		for (int j = 0; j < multi_linepoints[i].size(); j++)
		{
			outfile << fixed << setprecision(3) << multi_linepoints[i][j].x << " " << multi_linepoints[i][j].y << " " << multi_linepoints[i][j].z << " " << fixed << setprecision(0) << R << " " << G << " " << B << endl;
		}
		
	}
	outfile.close();
	cout << "结束" << endl;
	pcl::visualization::PCLVisualizer viewer("点云可视化");
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr new_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
	new_cloud->width = origipts.size();
	new_cloud->height = 1;
	new_cloud->is_dense = false;
	new_cloud->points.resize(new_cloud->width*new_cloud->height);

	
	
	int sumid = 0;
	for (int i = 0; i < multi_linepoints.size(); i++)
	{
		double R = rand() % 255;
		double G = rand() % 255;
		double B = rand() % 255;

		for (int j = 0; j < multi_linepoints[i].size(); j++)
		{
			new_cloud->points[sumid].x = multi_linepoints[i][j].x;
			new_cloud->points[sumid].y = multi_linepoints[i][j].y;
			new_cloud->points[sumid].z = multi_linepoints[i][j].z;
			new_cloud->points[sumid].r = R;
			new_cloud->points[sumid].g = G;
			new_cloud->points[sumid].b = B;
			sumid = sumid + 1;
		}

	}
	


	pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB>fildColor(new_cloud);
	viewer.setBackgroundColor(0, 0, 0);
	viewer.addPointCloud<pcl::PointXYZRGB>(new_cloud, fildColor, "inCloud");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "inCloud");
	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}

	system("pause");

}

属于同一直线的轮廓点,分组结果如上,结果比较理想。

3.3 点云旋转

//(3)原始点云进行旋转
void main()
{
	char *filepath = "D:\\testdata\\points.xyz";
	char *savepath = "D:\\testdata\\points_boundpts_transformpt.xyz";

	vector<pcl::PointXYZ> origipts = ReadPointXYZIntoVector(filepath);
	//假设其z坐标都为0,为平面坐标
	for (int i = 0; i < origipts.size(); i++)
	{
		origipts[i].z = 0;
	}

	vector<pcl::PointXYZ> boundpts, nonbounpts;
	double r = 0.8;
	Bounpts(origipts, r, boundpts, nonbounpts);

	pcl::PointXYZ center; 
	vector<pcl::PointXYZ> transpts;
	double ds_thres = 0.35;
	double linefit_knn = 5;
	double growing_knn = 5;
	TransformPts(origipts, r, ds_thres, linefit_knn, growing_knn, center, transpts);
	srand((int)time(0));
	ofstream outfile(savepath, ios::out);
	for (int i = 0; i < transpts.size(); i++)
	{		
		outfile << fixed << setprecision(3) << transpts[i].x << " " << transpts[i].y << " " << transpts[i].z << " " << endl;
	}
	outfile.close();
	cout << "结束" << endl;
	pcl::visualization::PCLVisualizer viewer("点云可视化");
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr new_cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
	new_cloud->width = origipts.size();
	new_cloud->height = 1;
	new_cloud->is_dense = false;
	new_cloud->points.resize(new_cloud->width*new_cloud->height);

	int sumid = 0;
	for (int i = 0; i < transpts.size(); i++)
	{
		new_cloud->points[sumid].x = transpts[i].x;
		new_cloud->points[sumid].y = transpts[i].y;
		new_cloud->points[sumid].z = transpts[i].z;
		new_cloud->points[sumid].r = 255;
		new_cloud->points[sumid].g = 255;
		new_cloud->points[sumid].b = 255;
	}

	pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB>fildColor(new_cloud);
	viewer.setBackgroundColor(0, 0, 0);
	viewer.addPointCloud<pcl::PointXYZRGB>(new_cloud, fildColor, "inCloud");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "inCloud");
	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}

	system("pause");

}

旋转前点云与水平方向存在一定旋转角,旋转后点云水平一致,旋转旋转成功。

代码与测试数据下载链接:https://mp.csdn.net/mp_download/manage/download/UpDetailed

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云实验室lab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值