#include <iostream>
#include <pcl/common/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/io/vtk_lib_io.h>//loadPolygonFileOBJ所属头文件;
#include <pcl/point_cloud.h>
#include <pcl/console/parse.h>
#include <pcl/common/transforms.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
#include <sstream>
#include <filesystem>
#include <fstream>
#include <direct.h>
#include <windows.h>
using namespace std;
using namespace pcl;
int main()
{
/*+++++++++++++++++++++++++单视角点云获取+++++++++++++++++++++++++++++++*/
//读取CAD模型
// 创建一个智能指针指向 vtkSTLReader 对象
vtkSmartPointer<vtkSTLReader> reader = vtkSmartPointer<vtkSTLReader>::New();
// 设置要读取的 STL 文件的文件名
//修改名字
reader->SetFileName("C://Users//l'c'r//source//repos//ConsoleApplication1//stldata//holer20d2.5.STL");
// 更新读取器以读取 STL 文件并填充输出数据
reader->Update();
// 创建一个智能指针指向 vtkPolyData 对象
vtkSmartPointer<vtkPolyData> polydata = vtkSmartPointer<vtkPolyData>::New();
// 将读取器的输出数据赋值给 vtkPolyData 对象
polydata = reader->GetOutput();
// 获取 vtkPolyData 对象中点的数量
polydata->GetNumberOfPoints();
//*+++++++++++++++++++++++++单视角点云获取+++++++++++++++++++++++++++++++*/
//主要是renderViewTesselatedSphere的参数设定
//输入
float resx = 512; //窗口x方向大小(即分辨率),分辨率越大,采样点云包含点的数目越多
float resy = 424; //窗口y方向大小(即分辨率),分辨率越大,采样点云包含点的数目越多
//使用了自定义的内存分配器。这个容器可以用来存储和管理多个点云数据。
std::vector<pcl::PointCloud<pcl::PointXYZ>, \
Eigen::aligned_allocator<pcl::PointCloud<pcl::PointXYZ> > > views_xyz;// 各视点点云对应的XYZ信息
//输出 4*4浮点数矩阵
std::vector<Eigen::Matrix4f, \
Eigen::aligned_allocator<Eigen::Matrix4f> > poses;// 从目标坐标变换到视点相机坐标
std::vector<float> entropies;//0-1之间,视点看到模型的百分比
//输入
int tesselation_level = 0;//表示在角度下的细分数
//对于原始二十面体三角形面的分割数,
//如果设为0,则是原始二十面体,
//设为1,每个三角形面会被分为4个三角形
//此时,形成的应该还是二十面体,但是顶点数变为了42(原始的12个顶点+每一个边上增加的顶点30)
float view_angle = 90;//虚拟相机的视场
float radius_sphere = 0.5;//radius_sphere半径 即相机围绕物体旋转的半径
bool use_vertices = FALSE;
//bool use_vertices = FALSE;//是否采用tessellated icosahedron 的vertices
//设为TRUE,则使用顶点,得到12个视角(tesselation_level = 0)或42个视角(tesselation_level = 1),
//设为FALSE,则使用面,得到20个视角(tesselation_level = 0)或80个视角(tesselation_level = 1)
//PCLVisualizer 显示
pcl::visualization::PCLVisualizer vis;
/*vis.setBackgroundColor(255,255,255,0);*/
vis.addModelFromPolyData(polydata, "mesh", 0);
vis.setRepresentationToSurfaceForAllActors();
/*
在 pcl::renderViewTesselatedSphere 函数中,poses 是作为输出参数传递的。当您调用这个函数时,
它会计算不同视角的刚性变换矩阵,并将这些矩阵存储在 poses 中。
这是 pcl::renderViewTesselatedSphere 函数的一部分功能,它会在函数执行过程中为每个视角计算刚性变换矩阵,
并将这些矩阵存储在 poses 中。您不需要手动为 poses 添加参数,而是该函数将为您执行这项工作。这是库的功能,允许您在不同视角之间对点云数据进行刚性变换,以进行后续处理或融合操作。
因此,poses 的值是在 pcl::renderViewTesselatedSphere 函数内部设置的,
您可以在函数调用后访问它以获取所有不同视角的刚性变换矩阵。
*/
vis.renderViewTesselatedSphere(resx, resy, views_xyz, poses, entropies, \
tesselation_level, view_angle, radius_sphere, use_vertices);//显示各角度点云
//修改名字
const char* path = "C:\\Users\\l'c'r\\source\\repos\\ConsoleApplication1\\modelpcd\\models\\holer20d2.5";
FILE* fp = NULL;
fp = fopen(path, "r");
if (NULL == fp) {
if (0 == _mkdir(path))
{
_chdir(path);
std::cout << "FTP文件夹创建成功,当前工作目录已更改" << std::endl;
//保存
for (int i = 0; i < views_xyz.size(); i++)
{
pcl::PointCloud<pcl::PointXYZ> views_cloud;
/*
*views_xyz[i] 是原始的点云数据,表示从不同视角获取的点云。
views_cloud 是用来存储经过变换后的点云数据的容器。
函数 pcl::transformPointCloud 将把变换后的数据存储在 views_cloud 中。
poses[i] 是刚性变换矩阵,它表示如何变换 views_xyz[i] 中的点云数据。
这个矩阵定义了平移、旋转和缩放等变换。
*/
pcl::transformPointCloud<pcl::PointXYZ>(views_xyz[i]/*输入点云*/, views_cloud/*输出点云*/, poses[i]/*刚性变换*/);
std::stringstream ss;
//修改名字
ss << "holer20d2.5_" << "cloud_view_" << i << ".pcd";
pcl::io::savePCDFile(ss.str(), views_cloud);
}
}
}
//显示原STL文件
while (!vis.wasStopped())
{
vis.spinOnce();
}
}
PCL库将STL文件进行多视角拍摄获得不同角度下点云文件
于 2023-11-23 14:29:22 首次发布