效果展示
代码
代码可直接运行
#include <string>
#include <vector>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iterator>
#include <boost/iterator/function_output_iterator.hpp>
#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>
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>;
// 定义一个迭代器
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;//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
int main(int argc, char* argv[]) {
//读取点云
std::ifstream in(argc > 1 ? argv[1] : CGAL::data_file_path("data/cube.xyz"));
CGAL::IO::set_ascii_mode(in);
if (!in) {
std::cout <<
"Error: cannot read the file point_set_3.xyz!" << std::endl;
std::cout <<
"You can either create a symlink to the data folder or provide this file by hand."
<< std::endl << std::endl;
return EXIT_FAILURE;
}
//插入法线
const bool with_normal_map = true;
Input_range input_range(with_normal_map);
in >> input_range;
in.close();
std::cout <<"* loaded "<< input_range.size() <<" points with normals" << std::endl;
//默认参数设置
const std::size_t k = 12;
const FT max_distance_to_plane = FT(1);
const FT max_accepted_angle = FT(20);
const std::size_t min_region_size = 200;
//区域增长
Neighbor_query neighbor_query(input_range,k, input_range.point_map());
Region_type region_type(input_range,max_distance_to_plane, max_accepted_angle, min_region_size, input_range.point_map(), input_range.normal_map());
Region_growing region_growing(input_range, neighbor_query, region_type);
Output_range output_range;
std::size_t number_of_regions = 0;
Insert_point_colored_by_region_index inserter(input_range, input_range.point_map(), output_range, number_of_regions);
CGAL::Timer timer;
timer.start();
region_growing.detect( boost::make_function_output_iterator(inserter));
timer.stop();
std::cout << "* " << number_of_regions <<" regions have been found in " << timer.time() << " seconds"<< std::endl;
if (argc > 2) {
const std::string path = argv[2];
const std::string fullpath = path + "regions_point_set_3.ply";
std::ofstream out(fullpath);
out << output_range;
std::cout << "* found regions are saved in " << fullpath << std::endl;
out.close();
}
return EXIT_SUCCESS;
}
结论
检测出20个区域平面 ,时间消耗0.764s。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END