PCL点云:点云数据结构_sensor_orientation_点云颠倒_点云反转_点云可视化与坐标系不匹配问题
刚接触PCL,记录一下掉进去过的几个坑“可视化点云的时候,点云反转了,与本来的坐标系不匹配了”仔细琢磨了半天,可能与pcl::PointCloud::sensor_orientation_ 这个结构有关系sensor_orientation_中有一个关键的值是 matrix().一般情况下sensor_orientation_.matrix()值是cloud->sensor_orientat
·
- 刚接触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();
}
更多推荐
所有评论(0)