网格数据的旋转平移变化
前言
PCL中点云旋转平移变换很常见,今天需要对网格旋转平移变换,发现没有专门的函数实现,所以专门实现一下。 |
一、点云旋转平移变换
首先,我们先实现一下点云的旋转平移变换。 |
//声明点云变量
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_trans(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
//加载点云
pcl::io::loadPCDFile(argv[1],*cloud);
//矩阵输入
Eigen::Matrix4f trans;
trans << 0.946657955647, - 0.173648178577, 0.271449804306 ,100,
0.166921347380 ,0.984807729721 ,0.047863926739 ,0.000000000000,
- 0.275637358427, 0.000000000000 ,0.961261689663, 0.000000000000,
0, 0, 0, 1;
pcl::transformPointCloud(*cloud ,*cloud_trans, trans);
核心就在 pcl::transformPointCloud(*cloud ,*cloud_trans, trans);
二、网格旋转平移变换
针对网格旋转变换,我们需要加载mesh网格,比如ply、off、stl、obj等格式,PCL中都提供了相应的加载方式 |
//------------------------------------------------------------
//声明网格变量
pcl::PolygonMesh mesh;
pcl::io::loadPolygonFileSTL(argv[1],mesh);
其次,我们查看mesh的组成,有header,cloud,polygons组成,其中cloud就是我们所说的点云,polygons则是面片顶点数据。若要进行旋转变换,只需对mesh中的cloud进行旋转平移即可,polygons记录的只是顶点顺序,变换后其本身也不改变。 |
知晓上述原理后,只要对mesh点云进行旋转变换即可,然后发现,mesh中的cloud定义如下:pcl::PointCloud2格式的,所以需要将其转化为pcl::PointCloud::Ptr格式,旋转变换后还需将其转回来。 |
- pcl::PointCloud2->pcl::PointCloud::Ptr
pcl::fromPCLPointCloud2(cloud2, *cloud);
- pcl::PointCloud::Ptr->pcl::PointCloud2
pcl::toPCLPointCloud2(*cloud_trans, cloud_trans2);
三、效果展示
- x平移200
- 随机变换
-
四、整体代码
#include <pcl/io/ply_io.h>
#include <pcl/PolygonMesh.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/io/pcd_io.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
using namespace std;
int main(int argc, char** argv)
{
//------------------------------------------------------------
//声明网格变量
pcl::PolygonMesh mesh;
pcl::io::loadPolygonFileSTL(argv[1],mesh);
//-----------------------------------------------------------
//将mesh分为cloud与polygons,其中cloud旋转变换,polygons不变
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_trans(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCLPointCloud2 cloud_trans2;
//----------------------------------------------------------
//将mesh中的cloud部分单独提出处理,由于mesh'中cloud是pcl::PointCloud2格式,需要先转换
auto cloud2 = mesh.cloud;
pcl::fromPCLPointCloud2(cloud2, *cloud);
//---------------------------------------------------------
//输入旋转平移(变换)矩阵
Eigen::Matrix4f trans;
trans << 0.946657955647, - 0.173648178577, 0.271449804306 ,100,
0.166921347380 ,0.984807729721 ,0.047863926739 ,0.000000000000,
- 0.275637358427, 0.000000000000 ,0.961261689663, 0.000000000000,
0, 0, 0, 1;
//--------------------------------------------------------
//将点云pcl::PointCloud2->pcl::PointCloud格式
pcl::transformPointCloud(*cloud ,*cloud_trans, trans);
pcl::toPCLPointCloud2(*cloud_trans, cloud_trans2);
//mesh处理
auto mesh_trans = mesh;
mesh_trans.cloud = cloud_trans2;
//-----------------------------------------------------
//可视化
pcl::visualization::PCLVisualizer viewer("viewer");
//viewer.addPointCloud(cloud_trans,"cloud");
viewer.addPolygonMesh(mesh, "mesh");
viewer.addPolygonMesh(mesh_trans, "mesh_trans");
viewer.setRepresentationToSurfaceForAllActors(); //网格模型以面片形式显示
viewer.spin();
return (0);
}
OVER!!!