PCL点云:点云数据结构_sensor_orientation_点云颠倒_点云反转_点云可视化与坐标系不匹配问题

  • 刚接触PCL,记录一下掉进去过的几个坑
  • “可视化点云的时候,点云反转了,与本来的坐标系不匹配了”
  • 仔细琢磨了半天,可能与pcl::PointCloud::sensor_orientation_ 这个结构有关系
  • sensor_orientation_中有一个关键的值是 matrix().
  • 一般情况下sensor_orientation_.matrix()值是
 cloud->sensor_orientation_ M =
 1 0 0
 0 1 0
 0 0 1
  • 当是以上单位矩阵的时候,点的坐标在可视化的时候是不会变化的
  • 个人认为,在可视化点云的时候,点云上的点会经过sensor_orientation_.matrix()这个矩阵仿射,然后投射到坐标系中,而且,在进行滤波等操作的时候,也只要考虑原始点云的情况,不要考虑经过sensor_orientation_.matrix()仿射后的点的情况
  • 比如有个点是a = [1,1,1] , 但是sensor_orientation_.matrix() = dig(-1,-1,-1) 对角矩阵
  • 我们可视化以后,在viewer中坐标系中显示a’ = [-1,-1,-1]
  • 这个时候我们想清除点a = [1 , 1 , 1], 虽然它在可视化坐标系的位置是a’ = [-1,-1,-1]
  • 我们想要过滤这个点a‘ = [-1,-1,-1]
  • 设置 setFilterFieldName(x); setFilterLimits(1, 1) 清除 x = 1的点
  • 执行完成后 a’ = [-1,-1,-1]就被清除了。

实验

  • 我们初始化一个点云集,可视化如下,他是一个 X Y Z 属于 [0,1]的正方形矩阵
  • 红色是x轴 绿色是y轴 蓝色是z轴
    在这里插入图片描述
  • 修改sensor_orientation_.matrix()的信息为
cloud->sensor_orientation_ M =
 1  0  0
 0 -1  0
 0  0 -1

在这里插入图片描述

  • 虽然点云中点的仍然是 x属于 [0,1] y属于[0,1] z属于[0,1];
  • 但是在可视化的时候,会经过 cloud->sensor_orientation 这个矩阵的仿射 即 这个矩阵乘上原始点
  • 1 0 0
    0 -1 0 * 原始点坐标 = 仿射后的点
    0 0 -1
  • 投射出来的点就在 x 属于[0,1] y属于[-1,0] z属于[-1,0];
  • 但是要注意的是 这些点的真实的坐标 仍然是 x属于 [0,1] y属于[0,1] z属于[0,1];
  • 比如我们当前情况下进行滤波操作 清除 Z (蓝色的轴)属于 [0 , 0.5]的点,
  • 但是滤波清除了 Z 属于 [-0.5 ,0]的点
  • 从上面的图上看,是不存在这些点的。
  • (个人认为是在进行滤波操作的时候,滤波也会考虑到仿射矩阵
    在这里插入图片描述
#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/passthrough.h>

typedef pcl::PointXYZ PointT;

int main() {
    
    

	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud2(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PCDReader reader;
	reader.read("table_scene_mug_stereo_textured.pcd", *cloud2);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	//创建随机点云
	cloud->width = 100000;
	cloud->height = 1;
	cloud->is_dense = false;
	cloud->resize(cloud->width * cloud->height);

	float a = 0, b = 1;
	for (size_t i = 0; i < cloud->points.size(); ++i)
	{
    
    
		cloud->points[i].x = rand() * 1.0 / RAND_MAX * (b - a) + a;
		cloud->points[i].y = rand() * 1.0 / RAND_MAX * (b - a) + a;
		cloud->points[i].z = rand() * 1.0 / RAND_MAX * (b - a) + a;
	}

	std::cout << " cloud->sensor_orientation_ M = \n" << cloud->sensor_orientation_.matrix() << std::endl;
	std::cout << " cloud2->sensor_orientation_ M = \n" << cloud2->sensor_orientation_.matrix() << std::endl;

	cloud->sensor_orientation_ = cloud2->sensor_orientation_;

	std::cout << " cloud->sensor_orientation_ M = \n" << cloud->sensor_orientation_.matrix() << std::endl;
	std::cout << " cloud2->sensor_orientation_ M = \n" << cloud2->sensor_orientation_.matrix() << std::endl;

	pcl::PassThrough<PointT> pass;
	pcl::PointCloud<PointT>::Ptr cloud_filtered(new pcl::PointCloud<PointT>);
	//设置直通滤波
	pass.setInputCloud(cloud);
	//设置处理字段是z轴
	pass.setFilterFieldName("z");
	//处理范围是0.0~1.5区间
	pass.setFilterLimits(0, 0.5);
	//设置是过滤区间内还是区间外
	pass.setFilterLimitsNegative(true);
	pass.filter(*cloud_filtered);

	pcl::visualization::PCLVisualizer viewer("v1");
	viewer.addPointCloud(cloud_filtered);
	viewer.addCoordinateSystem();
	viewer.spin();
}

Guess you like

Origin blog.csdn.net/weixin_42585456/article/details/121593006