北京市建設(shè)工程審核網(wǎng)站十大經(jīng)典事件營(yíng)銷案例分析
本節(jié)內(nèi)容主要涉及形狀檢測(cè)(Shape Detection)與形狀重建(Shape Reconstruction),具體算法步驟會(huì)在后續(xù)章節(jié)介紹。CGAL在6.0重點(diǎn)更新了形狀重建部分的一些模塊——?jiǎng)討B(tài)空間分割與動(dòng)態(tài)形狀重建等,也會(huì)在后續(xù)詳細(xì)介紹。官網(wǎng)上的效果和問題缺陷測(cè)試還需要一些時(shí)間驗(yàn)證,以及算法效率的實(shí)際測(cè)試。
題外話
泊松,前進(jìn),尺度這些重建算法本身都有相應(yīng)的局限性,用CGAL測(cè)試或者其他任意的第三方庫測(cè)試這些方法的時(shí)候我想也發(fā)現(xiàn)了,一些重建結(jié)果不理想或者出現(xiàn)問題是很容易發(fā)生的,所以需要嵌入0-3維的一些幾何特征,之后也會(huì)介紹如何把這些與神經(jīng)網(wǎng)絡(luò)相結(jié)合,以及一些混合建模手段,比如多項(xiàng)式連續(xù)與離散結(jié)合,各種幾何算子融合諸如此類等。
理論部分
形狀檢測(cè)
- 區(qū)域增長(zhǎng)法
- 點(diǎn)云形狀檢測(cè)的高效ransac
形狀重建
從點(diǎn)云重建多邊形曲面
源碼編譯相關(guān)問題
- 添加形狀檢測(cè)頭文件會(huì)報(bào)錯(cuò)
#include <CGAL/Shape_detection/Efficient_RANSAC.h>
報(bào)錯(cuò):
問題在模版定義部分有重復(fù),注釋掉這部分重復(fù)的代碼即可
-
c++常見模版問題
-
多邊形曲面重建部分需要SCIP/GLPK庫,否則不能用。關(guān)于scip的庫用2022編譯好了,可以看:
網(wǎng)盤 提取碼:0212
里面有zlib,tbb,soplex,scip,scip只編譯了涉及的這部分相關(guān)的,其他的關(guān)聯(lián)依賴自行編譯
例子
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/IO/read_points.h>
#include <CGAL/property_map.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Shape_detection/Efficient_RANSAC.h>
#include <CGAL/Polygonal_surface_reconstruction.h>#include <CGAL/Polygon_mesh_processing/orientation.h>#include <CGAL/Timer.h>#include <fstream>
#include <CGAL/IO/read_points.h>
#include <CGAL/property_map.h>
#include <CGAL/Point_with_normal_3.h>
#ifdef CGAL_USE_SCIP // defined (or not) by CMake scripts, do not define by hand#include <CGAL/SCIP_mixed_integer_program_traits.h>
typedef CGAL::SCIP_mixed_integer_program_traits<double> MIP_Solver;#elif defined(CGAL_USE_GLPK) // defined (or not) by CMake scripts, do not define by hand#include <CGAL/GLPK_mixed_integer_program_traits.h>
typedef CGAL::GLPK_mixed_integer_program_traits<double> MIP_Solver;#endifusing Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point_3 = Kernel::Point_3;
using Mesh = CGAL::Surface_mesh<Kernel::Point_3>;
// Point with normal, and plane index
typedef boost::tuple<Point, Vector, int> PNI;
typedef std::vector<PNI> Point_vector;
typedef CGAL::Nth_of_tuple_property_map<0, PNI> Point_map;
typedef CGAL::Nth_of_tuple_property_map<1, PNI> Normal_map;
typedef CGAL::Nth_of_tuple_property_map<2, PNI> Plane_index_map;typedef CGAL::Shape_detection::Efficient_RANSAC_traits<Kernel, Point_vector, Point_map, Normal_map> Traits;typedef CGAL::Shape_detection::Efficient_RANSAC<Traits> Efficient_ransac;
typedef CGAL::Shape_detection::Plane<Traits> Plane;
typedef CGAL::Shape_detection::Point_to_shape_index_map<Traits> Point_to_shape_index_map;typedef CGAL::Polygonal_surface_reconstruction<Kernel> Polygonal_surface_reconstruction;
typedef CGAL::Surface_mesh<Point> Surface_mesh; void test()
{Point_vector points;const std::string input_file = CGAL::data_file_path("..\\data\\cube.pwn");if (!CGAL::IO::read_points(input_file.c_str(), std::back_inserter(points),CGAL::parameters::point_map(Point_map()).normal_map(Normal_map()))){std::cerr << "Error: cannot read file " << input_file << std::endl;return;}CGAL::Timer t;t.start();// Shape detectionEfficient_ransac ransac;ransac.set_input(points);ransac.add_shape_factory<Plane>();std::cout << "Extracting planes...";t.reset();ransac.detect();Efficient_ransac::Plane_range planes = ransac.planes();std::size_t num_planes = planes.size();std::cout << " Done. " << num_planes << " planes extracted. Time: " << t.time() << " sec." << std::endl;// Stores the plane index of each point as the third element of the tuple.Point_to_shape_index_map shape_index_map(points, planes);for (std::size_t i = 0; i < points.size(); ++i) {// Uses the get function from the property map that accesses the 3rd element of the tuple.int plane_index = get(shape_index_map, i);points[i].get<2>() = plane_index;}std::cout << "Generating candidate faces...";t.reset();Polygonal_surface_reconstruction algo(points,Point_map(),Normal_map(),Plane_index_map());std::cout << " Done. Time: " << t.time() << " sec." << std::endl;Mesh model;std::cout << "Reconstructing...";t.reset();if (!algo.reconstruct<MIP_Solver>(model)) {std::cerr << " Failed: " << algo.error_message() << std::endl;return ;}const std::string& output_file("without_input_planes_result.off");if (CGAL::IO::write_OFF(output_file, model))std::cout << " Done. Saved to " << output_file << ". Time: " << t.time() << " sec." << std::endl;else {std::cerr << " Failed saving file." << std::endl;return ;}// Also stores the candidate faces as a surface mesh to a fileMesh candidate_faces;algo.output_candidate_faces(candidate_faces);const std::string& candidate_faces_file("without_input_planes_cube_candidate_faces.off");std::ofstream candidate_stream(candidate_faces_file.c_str());if (CGAL::IO::write_OFF(candidate_stream, candidate_faces))std::cout << "Candidate faces saved to " << candidate_faces_file << "." << std::endl;}
結(jié)果
without_input_planes_result.off:
without_input_planes_cube_candidate_faces.off: