代码编织梦想

基本效果如下:

 

主要代码如下:

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/IO/read_xyz_points.h>
#include <CGAL/IO/Writer_OFF.h>
#include <CGAL/Point_set_3/IO.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/remove_outliers.h>
#include <CGAL/grid_simplify_point_set.h>
#include <CGAL/compute_average_spacing.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/jet_estimate_normals.h>
#include <CGAL/pca_estimate_normals.h>
#include <CGAL/mst_orient_normals.h>
#include <CGAL/radial_orient_normals.h>
#include <CGAL/vcm_estimate_normals.h>
#define CGAL_USE_GLPK
#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;

#endif


#if defined(CGAL_USE_GLPK) || defined(CGAL_USE_SCIP)

#include <CGAL/Timer.h>

#include <fstream>


typedef CGAL::Exact_predicates_inexact_constructions_kernel		Kernel;

typedef Kernel::Point_3											Point;
typedef Kernel::Vector_3										Vector;

// Point with normal, and plane index
typedef boost::tuple<Point, Vector, int>						PNI;
typedef std::vector<PNI>										Point_vector;
//using Point_vector  = CGAL::Point_set_3<PNI>;
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::Sphere<Traits>                       Sphere;
typedef CGAL::Shape_detection::Cone<Traits>							Cone;
typedef CGAL::Shape_detection::Torus<Traits>						Torus;
typedef CGAL::Shape_detection::Cylinder<Traits>						Cylinder;

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;

/*
* This example first extracts planes from the input point cloud
* (using RANSAC with default parameters) and then reconstructs
* the surface model from the planes.
*/
/*

*/

// Boost includes.
#include <boost/function_output_iterator.hpp>

// CGAL includes.
#include <CGAL/Timer.h>
#include <CGAL/Random.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>

#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>

#include <CGAL/Shape_detection/Region_growing/Region_growing.h>
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_point_set.h>
#include <CGAL/jet_smooth_point_set.h>

class Index_map {

public:
	using key_type = std::size_t;
	using value_type = int;
	using reference = value_type;
	using category = boost::readable_property_map_tag;

	Index_map() { }
	template<typename PointRange>
	Index_map(
		const PointRange& points,
		const std::vector< std::vector<std::size_t> >& regions) :
		m_indices(new std::vector<int>(points.size(), -1)) {




		for (std::size_t i = 0; i < regions.size(); ++i)
			for (const std::size_t idx : regions[i])
				(*m_indices)[idx] = static_cast<int>(i);


		(*m_indices)[points.size() - 1] = regions.size();
		(*m_indices)[points.size() - 2] = regions.size();
	}

	inline friend value_type get(
		const Index_map& index_map,
		const key_type key) {

		const auto& indices = *(index_map.m_indices);
		return indices[key];
	}


	void bujiu()
	{

	}
public:
	std::shared_ptr< std::vector<int> > m_indices;
};
int  region_grow(std::string & filename)
{
	CGAL::Timer t;
	// Type declarations.
	using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;

	using FT = typename Kernel::FT;
	using Point_3 = typename Kernel::Point_3;
	using Vector_3 = typename Kernel::Vector_3;

	using Input_range = CGAL::Point_set_3<Point_3>;
	using Point_map = typename Input_range::Point_map;
	using Normal_map = typename Input_range::Vector_map;

	using Neighbor_query = CGAL::Shape_detection::Point_set::K_neighbor_query<Kernel, Input_range, Point_map>;
	using Region_type = CGAL::Shape_detection::Point_set::Least_squares_plane_fit_region<Kernel, Input_range, Point_map, Normal_map>;
	using Region_growing = CGAL::Shape_detection::Region_growing<Input_range, Neighbor_query, Region_type>;


	using Indices = std::vector<std::size_t>;
	using Output_range = CGAL::Point_set_3<Point_3>;
	using Points_3 = std::vector<Point_3>;
	using Traits = CGAL::Shape_detection::Efficient_RANSAC_traits
		<Kernel, Input_range, Input_range::Point_map, Input_range::Vector_map>;
	using Efficient_ransac = CGAL::Shape_detection::Efficient_RANSAC<Traits>;
	using Plane = CGAL::Shape_detection::Plane<Traits>;
	using Sphere = CGAL::Shape_detection::Sphere<Traits>;
	using Cone = CGAL::Shape_detection::Cone<Traits>;
	using Torus = CGAL::Shape_detection::Torus<Traits>;
	using Cylinder = CGAL::Shape_detection::Cylinder<Traits>;
	using Point_to_shape_index_map = CGAL::Shape_detection::Point_to_shape_index_map<Traits>;
	using Polygonal_surface_reconstruction = CGAL::Polygonal_surface_reconstruction<Kernel>;
	using Surface_mesh = CGAL::Surface_mesh<Point>;
	// Concurrency
	using Concurrency_tag = CGAL::Parallel_if_available_tag;
	// Define an insert iterator.
	struct Insert_point_colored_by_region_index {

		using argument_type = Indices;
		using result_type = void;

		using Color_map =
			typename Output_range:: template Property_map<unsigned char>;

		const Input_range& m_input_range;
		const   Point_map  m_point_map;
		Output_range& m_output_range;
		std::size_t& m_number_of_regions;

		Color_map m_red, m_green, m_blue;

		Insert_point_colored_by_region_index(
			const Input_range& input_range,
			const   Point_map  point_map,
			Output_range& output_range,
			std::size_t& number_of_regions) :
			m_input_range(input_range),
			m_point_map(point_map),
			m_output_range(output_range),
			m_number_of_regions(number_of_regions) {

			m_red =
				m_output_range.template add_property_map<unsigned char>("red", 0).first;
			m_green =
				m_output_range.template add_property_map<unsigned char>("green", 0).first;
			m_blue =
				m_output_range.template add_property_map<unsigned char>("blue", 0).first;
		}

		result_type operator()(const argument_type& region) {

			CGAL::Random rand(static_cast<unsigned int>(m_number_of_regions));
			const unsigned char r =
				static_cast<unsigned char>(64 + rand.get_int(0, 192));
			const unsigned char g =
				static_cast<unsigned char>(64 + rand.get_int(0, 192));
			const unsigned char b =
				static_cast<unsigned char>(64 + rand.get_int(0, 192));

			for (const std::size_t index : region) {
				const auto& key = *(m_input_range.begin() + index);

				const Point_3& point = get(m_point_map, key);
				const auto it = m_output_range.insert(point);

				m_red[*it] = r;
				m_green[*it] = g;
				m_blue[*it] = b;
			}
			++m_number_of_regions;
		}
	}; // Insert_point_colored_by_region_index


	// Load xyz data either from a local folder or a user-provided file.
	//std::ifstream  in("data/Tile_+015_+029-twohouser.xyz");
	std::string pathname = filename;//"D:\\testdata\\xyz\\Tile_+014_+029_1.xyz";
	std::ifstream  in(pathname);

	// Reading input in XYZ format
	Input_range point_set;
	if (!in || !CGAL::read_xyz_point_set(in, point_set))
	{
		std::cerr << "Can't read input file " << std::endl;
		return 0;
	}

	//Simplify point set
	//auto points_2_plane = [](Input_range& Input,std::vector< std::vector<std::size_t> > regions) {
	//	
	//};
	double spacing =  CGAL::compute_average_spacing<CGAL::Sequential_tag>(point_set, 70);
	auto gsim_it = CGAL::grid_simplify_point_set(point_set, spacing);
	point_set.remove(gsim_it, point_set.end());
	CGAL::jet_smooth_point_set<CGAL::Sequential_tag>(point_set, 24);
	point_set.collect_garbage();

	auto  box = CGAL::bounding_box(point_set.points().begin(), point_set.points().end());
	Point pminxy(box.xmin(), box.ymin(), box.zmin());
	Point pminz(box.xmax(), box.ymax(), box.zmin());
	point_set.insert(pminxy);
	point_set.insert(pminz);
	//if (point_set.has_normal_map())
	//{
	//	for (Input_range::iterator it = point_set.begin(); it != point_set.end(); ++it)
	//	{
	//		Vector n = point_set.normal(*it);
	//		n = -n / std::sqrt(n * n);
	//		point_set.normal(*it) = n;
	//	}
	//}
	//else
	//{
	if (point_set.has_normal_map())
		point_set.remove_normal_map();
	point_set.add_normal_map();
	CGAL::jet_estimate_normals<CGAL::Sequential_tag>(point_set, 8, point_set.parameters().degree_fitting(2));     // additional named parameter specific to jet_estimate_normals
	//}
	if (!point_set.has_normal_map())
	{
		std::cerr << " Failed: has_normal_map" << std::endl;
		return 0;
	}



	std::cout << "* loaded " << point_set.size() << " points with normals" << std::endl;

	// Default parameter values for the data file point_set_3.xyz.
	const std::size_t k = 16;
	const FT          max_distance_to_plane = FT(spacing * 1.21);
	const FT          max_accepted_angle = FT(35);
	const std::size_t min_region_size = 50;

	// Create instances of the classes Neighbor_query and Region_type.
	Neighbor_query neighbor_query(
		point_set,
		k,
		point_set.point_map());

	Region_type region_type(
		point_set,
		max_distance_to_plane, max_accepted_angle, min_region_size,
		point_set.point_map(), point_set.normal_map());

	// Create an instance of the region growing class.
	Region_growing region_growing(
		point_set, neighbor_query, region_type);

	// Run the algorithm.
	Output_range output_range;
	CGAL::Timer timer;
	std::vector< std::vector<std::size_t> > regions;

	timer.start();
	region_growing.detect(std::back_inserter(regions));

	std::size_t number_of_regions = 0;
	Insert_point_colored_by_region_index inserter(
		point_set, point_set.point_map(),
		output_range, number_of_regions);
	region_growing.detect(
		boost::make_function_output_iterator(inserter));
	timer.stop();

	// Print the number of found regions.
	std::cout << "* " << regions.size() << " regions have been found in " << timer.time() << " seconds"
		<< std::endl;
	std::string tmpply = pathname;
	tmpply = tmpply.replace(tmpply.find(".xyz"), 4, ".ply");
	const std::string path = tmpply;//"data/Tile_+015_+029-twohouser3333.ply";
	std::ofstream out(path);
	out << output_range;
	std::cout << "* found regions are saved in " << path << std::endl;
	out.close();


	Index_map index_map(point_set, regions);

	Polygonal_surface_reconstruction algo(
		point_set,
		point_set.point_map(),
		point_set.normal_map(),
		index_map);
	Surface_mesh model;

	std::cout << "Reconstructing...";


	if (!algo.reconstruct<MIP_Solver>(model, 0.43, 0.27, 0.3)) {
		std::cerr << " Failed: " << algo.error_message() << std::endl;
		return 0;
	}

	pathname = pathname.replace(pathname.find(".xyz"), 4, ".off");

	const std::string& output_file(pathname);
	std::ofstream output_stream(output_file.c_str());
	if (output_stream && CGAL::write_off(output_stream, model)) {
		// flush the buffer
		output_stream << std::flush;
		std::cout << " Done. Saved to " << output_file << ". Time: " << t.time() << " sec." << std::endl;
	}
	else {
		std::cerr << " Failed saving file." << std::endl;
		return 0;
	}
	return 1;
}

此方案需要先将房子一栋栋分开, 目前没研究, 房子是手动分开, 一栋栋处理的, CGAL使用版本5.1.5,boost6.18,gplk库

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/chijingjing/article/details/127105490

三维重建pcl:点云单侧面正射投影_wishchin的博客-爱代码爱编程_pcl 投影

        终于把点云单侧面投影正射投影的代码写完了,为一个阶段,主要使用平面插值方法,且只以XOY平面作为的正射投影面。有些凑合的地方,待改进。         方法思路:使用Mesh模型,对每一个表面进行表面重建。借助OpenCV Mat类型对投影平面进行内点判断,对内点位置进行插值。         OpenCV cv::polylines

三维重建:三维重建技术概述_oomelloo的博客-爱代码爱编程

基于视觉的三维重建,指的是通过摄像机获取场景物体的数据图像,并对此图像进行分析处理,再结合计算机视觉知识推导出现实环境中物体的三维信息。 1. 相关概念 (1)彩色图像与深度图像 彩色图像也叫作RGB图像,R、G、B三个分量对应于红、绿、蓝三个通道的颜色,它们的叠加组成了图像像素的不同灰度级。RGB颜色空间是构成多彩现实世界的基础。深度图像又被称

点云重建/点云三角化/网格化-爱代码爱编程

点云重建/点云三角化/网格化 rgbd传感器获取的数据通常是大量的三维点,后期的处理过程都是在对这些点的坐标进行处理。而在3D打印邻域,仅仅依靠这些点坐标是无法进行打印的。而点云网格化就可以把点云转换为mesh模型(类似UG/Solidworks软件到处的模型),有了mesh模型后,就可以进行后续的打印了。 点云网格化 点云网格化是使用一系列的网格来

CGAL功能介绍-爱代码爱编程

目前还没用过CGAL,只知道可以用于计算机图形学,所以先记录下来,方便日后查阅。 算术与代数Arithmetic and Algebra 主要提供了计算几何用到的数学基础:数据类型、多项式、数据结构与算法 代数基础Algebraic Foundations 这个包从概念、类和函数的角度定义了代数对CGAL的意义。 数据类型Number Type

CGAL: Point Set Processing-爱代码爱编程

Point Set Procesing这个包主要是为了预处理点云的一些基本操作,如下图所示,通过一系列操作之后使得输出点云(右边)比输入(左边)更加的稀疏、平滑、没那么多噪点和异常值。 框架步骤: 1. Points with normals 点及法向量 KNN:反映点云集合的密度Average spacing:所有点到K最近邻点的平均间距

经典点云去噪算法总结-爱代码爱编程

以下列出方法均有运行成功的代码,所有工程文件我都会放在如下链接: 待补充   1.移动最小二乘MLS 基于PCL #include "stdafx.h" #include <pcl/point_types.h> #include <pcl/io/pcd_io.h> #include <pcl/kdtree/kdt

点云三角化基本流程-爱代码爱编程

也叫做点云重建/点云网格化,使用一系列的网格来近似你和点云,在图形学中,一般使用三角网格或四角网格 读取点云 读入原始点云,从图中可以看出点云分辨率很高,会使得计算量很大;而且存在很多离群点和噪声 点云下采样 将原始点云稀疏化,降低计算量 去除离群点 三角化算法对离群点比较敏感 点云平滑 由于传感器自身的测量噪声,得到的点云会有些波动,通过计算法

CGAL模块介绍-爱代码爱编程

目前还没用过CGAL,只知道可以用于计算机图形学,所以先记录下来,方便日后查阅。 算术与代数Arithmetic and Algebra 主要提供了计算几何用到的数学基础:数据类型、多项式、数据结构与算法 代数基础Algebraic Foundations 这个包从概念、类和函数的角度定义了代数对CGAL的意义。 数据类型Number Types 这个包为第三方

点云重建方法汇总一(pcl-cgal)_小修勾的博客-爱代码爱编程

点云重建方法汇总一(PCL-CGAL) 一、前言二、效果展示2.1 PCL中实现2.2 CGAL中实现三、后续 一、前言 前几天抽空把PCL中和CGAL中常见的重建方法都跑了一下,今天在这里做一下总结。 一、主要方法: PCLCGAL凹包Advancing Front凸包Scale Space泊松泊松贪婪二、数据: 以bunny数据为例

点云处理,点云处理算法程序_yzx_xyz的博客-爱代码爱编程

点云处理,算法程序代编,top5硕博团队,高质量的服务。基于pcl,cgal程序代编。联系方式:🐧🐧(q)958417691 或闲鱼id专业点云处理。 1.点云分割。单木分割,林下地形提取,DEM制作,等高线制作,地形补洞。 2.点云重建。多种方法点云重建模型。 3.点云配准。大坝,隧道,孔洞等变形监测,重叠度评估。 4.点云体素化,点云网格化,以

cgal例程:点云数据三维重建_点云三维重建-爱代码爱编程

作者:西蒙·吉罗多 链接:CGAL 5.4 - Manual: Surface Reconstruction from Point Cloudshttps://doc.cgal.org/latest/Manual/tuto_reconstruction.html 目录 2 我应该使用哪种算法? 3 管道概览 4 读取点云数据 5 点云预处理

cgal 点云数据生成dsm、dtm、等高线和数据分类_sam 点云 dem-爱代码爱编程

目录 1、不规则三角网(TIN)2、数字表面模型(DSM)3、数字地形模型(DTM)3.1 带有信息的TIN3.2 识别连接组件3.3 数据清洗3.4 孔洞填充和网格重建 4 光栅化5 等高线生成5.1绘