点云旋转处理

实现代码为:

//以中心化点进行旋转
	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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/387932.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SPFA最短路

文章目录 从Bellman-Ford开始核心思想模拟算法执行过程时间复杂度模板 spfaspfa优化的思想模板 从Bellman-Ford开始 对于所有边权都大于等于0的图&#xff0c;任意两个顶点之间的最短路&#xff0c;显然不会经过重复的顶点或者边。也就是说任意一条最短路经过的定点数不会超过…

动态内存管理:new和delete的底层探索

之前我们在C语言上是学过malloc和calloc还要realloc等函数来在堆上获取相应的内存&#xff0c;但是这些函数是存在缺陷的&#xff0c;今天引入对new和delete的学习&#xff0c;来了解new和delete的底层实现。 首先就是在C中我们为什么要对内存进行区域的分块&#xff1f; 答案…

MyBatisPlus基础操作之增删改查

目录 一、基本使用 1.1 插入数据 1.2 删除操作 1.3 更新操作 二、条件构造器Wrapper 2.1 常用AbstractWrapper方法 2.1.1 示例一 2.2.2 示例二 2.2.3 示例三 2.2 常用QueryWrapper方法 2.2.1 示例一 2.2.2 示例二 2.2.3 示例三&#xff08;常用&#xff09; 2.3 常…

攻防演练后的一点随记

攻防演练 攻防演练算是告一段落了&#xff0c;各位红队和蓝队的兄弟们都辛苦了&#xff0c;写一点随记&#xff0c;供大家参考。 记得第一次参加攻防演练是在2018年&#xff0c;当时被派到北京&#xff0c;在某个政企单位做攻防演练支撑工作&#xff0c;然后2020年又被紧急派到…

【STM32 CubeMX】学STM必会的数据结构——环形缓冲区

文章目录 前言一、环形缓冲区是什么二、实现环形缓冲区实现分析2.1 环形缓冲区初始化2.2 写buf2.3 读buf2.4 测试 三、代码总况总结 前言 在嵌入式系统开发中&#xff0c;经常需要处理数据的缓存和传输&#xff0c;而环形缓冲区是一种常见且有效的数据结构&#xff0c;特别适用…

提前部署游戏业务防护,为何如此重要?

现在做网络游戏的企业都知道服务器的安全对于我们来说很重要&#xff01;互联网上面的DDoS攻击和CC攻击等等无处不在&#xff0c;而游戏服务器对服务器的防御能力和处理能力要求更高&#xff0c;普通的服务器则是比较注重各方面能力的均衡。 随着游戏行业的壮大&#xff0c;网络…

java 宠物在线商城系统Myeclipse开发mysql数据库web结构jsp编程servlet计算机网页项目

一、源码特点 java 宠物在线商城系统是一套完善的java web信息管理系统 servletdaobean mvc模式&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S 模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&…

尚硅谷最新Node.js 学习笔记(三)

目录 六、Node.js 模块化 6.1、介绍 什么是模块化与模块&#xff1f; 什么是模块化项目&#xff1f; 模块化好处 6.2、模块暴露数据 模块初体验 暴露数据 6.3、导入&#xff08;引入&#xff09;模块 6.4、导入模块的基本流程 6.5、CommonJS规范 七、包管理工具 7…

站在C/C++的肩膀速通Java面向对象

默认学过C或C&#xff0c;对变量、表达式、选择、循环都会。 运行特征 解释型语言&#xff08;JavaScript、Python等&#xff09; 源文件-(平台专属解释器)->解释器中执行编译型语言&#xff08;C、Go等&#xff09; 源文件-(平台编译器)->平台可执行文件Java 源文件-(…

算法详解:滑动窗口-- 最大连续1的个数 III

题目来源:力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 本期讲解滑动窗口经典例题,我会从三个点开始讲解题目1.题目解析2.算法原理 3.编写代码 1.题目解析 这道题目理解起来还是比较简单的,我们简单分析一下,也就是给定一个数组,数组是由1和0组成…

AtCoder Beginner Contest 335 (Sponsored by Mynavi) --- F - Hop Sugoroku -- 题解

目录 F - Hop Sugoroku 题目大意&#xff1a; 思路解析&#xff1a; 代码实现&#xff1a; F - Hop Sugoroku 题目大意&#xff1a; 思路解析&#xff1a; 容易想到这是一个dp题&#xff0c;然后初始转移方程为&#xff1a; 如果当a[i] 较大时&#xff0c;时间复杂度为 O(N…

【AI视野·今日NLP 自然语言处理论文速览 第七十九期】Thu, 18 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Thu, 18 Jan 2024 Totally 35 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Deciphering Textual Authenticity: A Generalized Strategy through the Lens of Large Language Semantics …

MySQL数据库-MVCC多版本并发控制

mvcc,多版本并发控制&#xff08;Multi-Version Concurrency Control&#xff09;,是一种用于数据库管理系统中的并发控制方法. 在传统的并发控制方法中,如锁定机制,当一个事务修改数据时,会对相关的数据对象进行锁定,其他事务需要等待该锁释放才能进行操作。这种方法存在着事…

操作系统-408

一、操作系统概述 1、定义 负责协调软件和硬件的计算机资源的工作为上层应用提供简易的服务操作系统是系统软件 2、功能&#xff1a; 操作系统是系统资源的管理者 处理机管理存储器管理文件管理设备管理向上层提供方便易用的服务 命令接口程序接口对硬件机器的扩展 3、特征…

详解tomcat中的jmx监控

目录 1.概述 2.如何开启tomcat的JMX 3.tomcat如何实现JMX的源码分析 1.概述 本文是博主JAVA监控技术系列文章的第二篇&#xff0c;前面一篇文章中我们介绍了JAVA监控技术的基石——jmx&#xff1a; 【JMX】JAVA监控的基石-CSDN博客 本文我们将从使用和源码实现两个方面聊…

springboot743二手交易平台

springboot743二手交易平台 获取源码——》公主号&#xff1a;计算机专业毕设大全

Python面向对象学习小记——面向过程VS面向对象

【面向过程就好比你是一个工人&#xff0c;你得亲自去做一个个任务 面向对象就好比你一个包工头&#xff0c;你可以差遣你下面的工人去做】

日期类运算符重载以及const成员详细解析

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言进阶 数据结构初阶 Linux C初阶 算法 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂 目录 一.前言 二.运算符重载 2.1概念 2.2比较的符号重载 2.2.1…

linux 安装docker

目录 环境 操作步骤 1 下载脚本 2 执行脚本 3 检查docker版本&#xff0c;证明安装成功 环境 阿里云 ubuntu 22.04 64位 操作步骤 参考linux系统安装docker-腾讯云开发者社区-腾讯云 (tencent.com) 1 下载脚本 curl -fsSL https://get.docker.com -o get-docker.sh …

JavaWeb学习|Filter与ThreadLocal

学习材料声明 所有知识点都来自互联网&#xff0c;进行总结和梳理&#xff0c;侵权必删。 引用来源&#xff1a;尚硅谷最新版JavaWeb全套教程,java web零基础入门完整版 Filter 1、Filter 过滤器它是 JavaWeb 的三大组件之一。三大组件分别是&#xff1a;Servlet 程序、Liste…