Я хотел бы использовать функции и классы из обеих библиотек (CGAL и PCL). Следовательно, ему необходимо преобразовать обработанные данные из одних в другие.
Итак, как мне преобразовать точки в CGAL в облака точек в pcl и наоборот?
Я хотел бы использовать функции и классы из обеих библиотек (CGAL и PCL). Следовательно, ему необходимо преобразовать обработанные данные из одних в другие.
Итак, как мне преобразовать точки в CGAL в облака точек в pcl и наоборот?
Учитывая заголовки:
#include <pcl/point_types.h>
#include <pcl/conversions.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Simple_cartesian.h>
Вот функция для преобразования из PCL в CGAL
int convert_mesh_from_PCL_to_CGAL(pcl::PolygonMesh::Ptr PCL_mesh, CGAL_Mesh& CGAL_mesh)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr mesh_cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::fromPCLPointCloud2( PCL_mesh->cloud, *mesh_cloud );
// clear and reserve the
CGAL_mesh.clear();
int n = mesh_cloud->size();
int f = PCL_mesh->polygons.size();
int e = 0;
CGAL_mesh.reserve(n, 2*f, e);
//copy the vertices
double x, y, z;
for (int i=0; i<mesh_cloud->size(); i++)
{
Point p;
x = mesh_cloud->points[i].x;
y = mesh_cloud->points[i].y;
z = mesh_cloud->points[i].z;
p = Point(x, y, z);
CGAL_mesh.add_vertex(p);
}
// copy the faces
std::vector <int> vertices;
for(int i=0; i<PCL_mesh->polygons.size(); i++)
{
vertices.resize(3);
vertices[0] = PCL_mesh->polygons[i].vertices[0];
vertices[1] = PCL_mesh->polygons[i].vertices[1];
vertices[2] = PCL_mesh->polygons[i].vertices[2];
CGAL_mesh.add_face(CGAL_Mesh::Vertex_index (vertices[0]),
CGAL_Mesh::Vertex_index (vertices[1]),
CGAL_Mesh::Vertex_index (vertices[2]));
}
return 0;
}
От CGAL до PCL у меня был код с комментариями, я попытаюсь протестировать его и обновить позже, но это может дать вам представление о том, как это сделать.
int convert_mesh_from_CGAL_to_PCL(CGAL_Mesh CGAL_mesh, pcl::PolygonMesh::Ptr old_PCL_mesh, pcl::PolygonMesh::Ptr PCL_mesh)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr mesh_cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::fromPCLPointCloud2( old_PCL_mesh->cloud, *mesh_cloud );
int i=0;
BOOST_FOREACH(CGAL_vertex v, vertices(CGAL_mesh))
{
mesh_cloud->points[i].x = CGAL_mesh[v].point.x();
mesh_cloud->points[i].y = CGAL_mesh[v].point.y();
mesh_cloud->points[i].z = CGAL_mesh[v].point.z();
i++;
}
//BOOST_FOREACH(CGAL_vertex v, vertices(CGAL_mesh))
//BOOST_FOREACH(CGAL_face f, faces(CGAL_mesh))
pcl::toPCLPointCloud2( *mesh_cloud, PCL_mesh->cloud );
return 0;
}
Это не так уж сложно. Вот простой пример:
Во-первых, вам могут понадобиться заголовки:
#include <CGAL/Simple_cartesian.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <utility> // std::tuple
#include <vector>
Некоторые using
объявления облегчают жизнь.
(В примерах CGAL часто используются typedef
, например этот.)
// CGAL using declarations
using Kernel = CGAL::Simple_cartesian<float>;
using Point = Kernel::Point_3;
using Vector = Kernel::Vector_3;
using Color = std::array<unsigned char, 3>;
using PNC = std::tuple<Point, Vector, Color>;
// PCL using declarations
using Cloud = pcl::PointCloud<pcl::PointXYZRGBNormal>;
Чтобы преобразовать точки CGAL в облако точек PCL:
Cloud cgal2pcl(const std::vector<PNC> & points)
{
Cloud cloud;
for (const auto & pnc : points) {
const Point & p = std::get<0>(pnc);
const Vector & v = std::get<1>(pnc);
const Color & c = std::get<2>(pnc);
pcl::PointXYZRGBNormal pt;
pt.x = p.x();
pt.y = p.y();
pt.z = p.z();
pt.normal_x = v.x();
pt.normal_y = v.y();
pt.normal_z = v.z();
pt.r = c[0];
pt.g = c[1];
pt.b = c[2];
cloud.points.push_back(pt);
}
return cloud;
}
И от облака точек PCL до точек CGAL:
std::vector<PNC> pcl2cgal(const Cloud & cloud)
{
std::vector<PNC> points;
points.reserve(cloud.points.size());
for (const auto & pt : cloud.points) {
Point p (pt.x, pt.y, pt.z );
Vector n (pt.normal_x, pt.normal_y, pt.normal_z);
Color c { {pt.r, pt.g, pt.b} };
points.push_back(std::make_tuple(p, n, c));
}
return points;
}
В вашем конкретном примере вы можете изменить std::tuple<Point, Vector, Color>
на std::pair<Point, Vector>
, чтобы сохранить pcl::PointNormal
.
И если вам нужно pcl::PointXYZ
, то std::vector<Point>
может просто удовлетворить ваши потребности.