1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 【PCL】SolidWorks 三维建模 STL OBJ 采样生成 PCD 点云数据(附源码)

【PCL】SolidWorks 三维建模 STL OBJ 采样生成 PCD 点云数据(附源码)

时间:2024-05-11 18:58:18

相关推荐

【PCL】SolidWorks 三维建模 STL  OBJ 采样生成 PCD 点云数据(附源码)

目录&索引

1 前言2 准备工作(相关软件及库)3 实现步骤3.1 三维建模保存 stl 网格文件3.2 stl网格文件转 obj 网格文件a) 在工具里勾选 SW 插件 ScanTo3D,后续格式保存要用b) 以 ScanTo3D 网格文件打开保存的 stlc) 另存为 ScanTo3D(*.obj) 文件3.3 利用 PCL 采样可执行程序,实现 obj 网格文件转 pcd 点云a) 接下来就是最重要的两步了,在安装 PCL 的路径下 bin 文件夹打开,找到 pcl_mesh_sampling_debug.exe 或 pcl_mesh_sampling_release.exeb) cmd 运行可执行采样文件(obj 文件相同目录)4 结果5 mesh_sampling 源码(应读者需求,已更新)

这阵子做线结构光视觉检测(钢轨磨耗检测)项目的过程中,发现之前的许多知识点在逐渐遗忘,常言好记性不如烂笔头,故决定把项目中所用到的,把笔者认为有价值且对博友能够产生帮助的内容,记录分享于此。能力有限,如有纰漏,希望博友留下意见与建议。

1 前言

磨耗检测项目中,配准阶段将结构光采集的数据集映射到标准廓形的数据集上,以识别其特征,进而计算分析。

其中,建立标准轨头廓形数据模型有两种方法,a)分段函数描述;b)三维模型转 PCD(所选方案);

选定方案之后,查阅三维模型提取点云数据的相关资料时,发现在 SolidWorks 三维模型中提取生成点云数据的资料较少,且需要下载相关软件或配置需求过高。于是在笔者仔细查阅相关资料后,总结了一种较为方便且利于没有这方面基础的小白阅读完成。


2 准备工作(相关软件及库)

SolidWorks 等三维建模软件PCL 点云库

3 实现步骤

3.1 三维建模保存 stl 网格文件

3.2 stl网格文件转 obj 网格文件

a) 在工具里勾选 SW 插件 ScanTo3D,后续格式保存要用

b) 以 ScanTo3D 网格文件打开保存的 stl

c) 另存为 ScanTo3D(*.obj) 文件

3.3 利用 PCL 采样可执行程序,实现 obj 网格文件转 pcd 点云

a) 接下来就是最重要的两步了,在安装 PCL 的路径下 bin 文件夹打开,找到 pcl_mesh_sampling_debug.exe 或 pcl_mesh_sampling_release.exe

b) cmd 运行可执行采样文件(obj 文件相同目录)


4 结果

结果显示,点云文件获取完毕

当前目录下生成 60kg╱m 钢轨-05.pcd 的文件。下采样控制体素点距或投影模型等相关后续必要操作,标准点云模型满足需求。

如有不明白的地方,欢迎交流。


5 mesh_sampling 源码(应读者需求,已更新)

/** Software License Agreement (BSD License)** Point Cloud Library (PCL) - * Copyright (c) -, Willow Garage, Inc.** All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:** * Redistributions of source code must retain the above copyright*notice, this list of conditions and the following disclaimer.* * Redistributions in binary form must reproduce the above*copyright notice, this list of conditions and the following*disclaimer in the documentation and/or other materials provided*with the distribution.* * Neither the name of the copyright holder(s) nor the names of its*contributors may be used to endorse or promote products derived*from this software without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE* POSSIBILITY OF SUCH DAMAGE.**/#include <pcl/visualization/pcl_visualizer.h>#include <pcl/io/pcd_io.h>#include <pcl/common/transforms.h>#include <vtkPLYReader.h>#include <vtkOBJReader.h>#include <vtkTriangle.h>#include <vtkTriangleFilter.h>#include <vtkPolyDataMapper.h>#include <pcl/filters/voxel_grid.h>#include <pcl/console/print.h>#include <pcl/console/parse.h>inline doubleuniform_deviate (int seed){double ran = seed * (1.0 / (RAND_MAX + 1.0));return ran;}inline voidrandomPointTriangle (float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3,Eigen::Vector4f& p){float r1 = static_cast<float> (uniform_deviate (rand ()));float r2 = static_cast<float> (uniform_deviate (rand ()));float r1sqr = sqrtf (r1);float OneMinR1Sqr = (1 - r1sqr);float OneMinR2 = (1 - r2);a1 *= OneMinR1Sqr;a2 *= OneMinR1Sqr;a3 *= OneMinR1Sqr;b1 *= OneMinR2;b2 *= OneMinR2;b3 *= OneMinR2;c1 = r1sqr * (r2 * c1 + b1) + a1;c2 = r1sqr * (r2 * c2 + b2) + a2;c3 = r1sqr * (r2 * c3 + b3) + a3;p[0] = c1;p[1] = c2;p[2] = c3;p[3] = 0;}inline voidrandPSurface (vtkPolyData * polydata, std::vector<double> * cumulativeAreas, double totalArea, Eigen::Vector4f& p){float r = static_cast<float> (uniform_deviate (rand ()) * totalArea);std::vector<double>::iterator low = std::lower_bound (cumulativeAreas->begin (), cumulativeAreas->end (), r);vtkIdType el = vtkIdType (low - cumulativeAreas->begin ());double A[3], B[3], C[3];vtkIdType npts = 0;vtkIdType *ptIds = NULL;polydata->GetCellPoints (el, npts, ptIds);polydata->GetPoint (ptIds[0], A);polydata->GetPoint (ptIds[1], B);polydata->GetPoint (ptIds[2], C);randomPointTriangle (float (A[0]), float (A[1]), float (A[2]), float (B[0]), float (B[1]), float (B[2]), float (C[0]), float (C[1]), float (C[2]), p);}voiduniform_sampling (vtkSmartPointer<vtkPolyData> polydata, size_t n_samples, pcl::PointCloud<pcl::PointXYZ> & cloud_out){polydata->BuildCells ();vtkSmartPointer<vtkCellArray> cells = polydata->GetPolys ();double p1[3], p2[3], p3[3], totalArea = 0;std::vector<double> cumulativeAreas (cells->GetNumberOfCells (), 0);size_t i = 0;vtkIdType npts = 0, *ptIds = NULL;for (cells->InitTraversal (); cells->GetNextCell (npts, ptIds); i++){polydata->GetPoint (ptIds[0], p1);polydata->GetPoint (ptIds[1], p2);polydata->GetPoint (ptIds[2], p3);totalArea += vtkTriangle::TriangleArea (p1, p2, p3);cumulativeAreas[i] = totalArea;}cloud_out.points.resize (n_samples);cloud_out.width = static_cast<uint32_t> (n_samples);cloud_out.height = 1;for (i = 0; i < n_samples; i++){Eigen::Vector4f p;randPSurface (polydata, &cumulativeAreas, totalArea, p);cloud_out.points[i].x = p[0];cloud_out.points[i].y = p[1];cloud_out.points[i].z = p[2];}}using namespace pcl;using namespace pcl::io;using namespace pcl::console;int default_number_samples = 100000;float default_leaf_size = 0.01f;voidprintHelp (int, char **argv){print_error ("Syntax is: %s input.{ply,obj} output.pcd <options>\n", argv[0]);print_info (" where options are:\n");print_info (" -n_samples X= number of samples (default: ");print_value ("%d", default_number_samples);print_info (")\n");print_info (" -leaf_size X = the XYZ leaf size for the VoxelGrid -- for data reduction (default: ");print_value ("%f", default_leaf_size);print_info (" m)\n");}/* ---[ */intmain (int argc, char **argv){print_info ("Convert a CAD model to a point cloud using uniform sampling. For more information, use: %s -h\n",argv[0]);if (argc < 3){printHelp (argc, argv);return (-1);}// Parse command line argumentsint SAMPLE_POINTS_ = default_number_samples;parse_argument (argc, argv, "-n_samples", SAMPLE_POINTS_);float leaf_size = default_leaf_size;parse_argument (argc, argv, "-leaf_size", leaf_size);// Parse the command line arguments for .ply and PCD filesstd::vector<int> pcd_file_indices = parse_file_extension_argument (argc, argv, ".pcd");if (pcd_file_indices.size () != 1){print_error ("Need a single output PCD file to continue.\n");return (-1);}std::vector<int> ply_file_indices = parse_file_extension_argument (argc, argv, ".ply");std::vector<int> obj_file_indices = parse_file_extension_argument (argc, argv, ".obj");if (ply_file_indices.size () != 1 && obj_file_indices.size () != 1){print_error ("Need a single input PLY/OBJ file to continue.\n");return (-1);}vtkSmartPointer<vtkPolyData> polydata1;if (ply_file_indices.size () == 1){vtkSmartPointer<vtkPLYReader> readerQuery = vtkSmartPointer<vtkPLYReader>::New ();readerQuery->SetFileName (argv[ply_file_indices[0]]);}else if (obj_file_indices.size () == 1){vtkSmartPointer<vtkOBJReader> readerQuery = vtkSmartPointer<vtkOBJReader>::New ();readerQuery->SetFileName (argv[obj_file_indices[0]]);polydata1 = readerQuery->GetOutput ();polydata1->Update ();}//make sure that the polygons are triangles!vtkSmartPointer<vtkTriangleFilter> triangleFilter = vtkSmartPointer<vtkTriangleFilter>::New ();triangleFilter->SetInput (polydata1);triangleFilter->Update ();vtkSmartPointer<vtkPolyDataMapper> triangleMapper = vtkSmartPointer<vtkPolyDataMapper>::New ();triangleMapper->SetInputConnection (triangleFilter->GetOutputPort ());triangleMapper->Update();polydata1 = triangleMapper->GetInput();polydata1->Update ();bool INTER_VIS = false;bool VIS = true;if (INTER_VIS){visualization::PCLVisualizer vis;vis.addModelFromPolyData (polydata1, "mesh1", 0);vis.setRepresentationToSurfaceForAllActors ();vis.spin();}pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_1 (new pcl::PointCloud<pcl::PointXYZ>);uniform_sampling (polydata1, SAMPLE_POINTS_, *cloud_1);if (INTER_VIS){visualization::PCLVisualizer vis_sampled;vis_sampled.addPointCloud (cloud_1);vis_sampled.spin ();}// VoxelgridVoxelGrid<PointXYZ> grid_;grid_.setInputCloud (cloud_1);grid_.setLeafSize (leaf_size, leaf_size, leaf_size);grid_.filter (*cloud_1);if (VIS){visualization::PCLVisualizer vis3 ("VOXELIZED SAMPLES CLOUD");vis3.addPointCloud (cloud_1);vis3.spin ();}savePCDFileASCII (argv[pcd_file_indices[0]], *cloud_1);}


本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。