added free functions and new examples

This commit is contained in:
Dmitry Anisimov 2021-03-22 13:22:32 +01:00
parent 3ae46dd890
commit b971f6a0e2
11 changed files with 358 additions and 24 deletions

View File

@ -15,10 +15,12 @@ include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program(
"benchmark_region_growing_on_point_set_2.cpp")
target_link_libraries(benchmark_region_growing_on_point_set_2
PUBLIC CGAL::Eigen3_support)
target_link_libraries(
benchmark_region_growing_on_point_set_2
PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program(
"benchmark_region_growing_on_point_set_3.cpp")
target_link_libraries(benchmark_region_growing_on_point_set_3
PUBLIC CGAL::Eigen3_support)
target_link_libraries(
benchmark_region_growing_on_point_set_3
PUBLIC CGAL::Eigen3_support)
endif()

View File

@ -15,17 +15,13 @@ include(CGAL_Eigen3_support)
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("efficient_RANSAC_basic.cpp")
create_single_source_cgal_program("efficient_RANSAC_with_callback.cpp")
create_single_source_cgal_program(
"efficient_RANSAC_and_plane_regularization.cpp")
create_single_source_cgal_program("efficient_RANSAC_and_plane_regularization.cpp")
create_single_source_cgal_program("region_growing_basic.cpp")
create_single_source_cgal_program("region_growing_with_lines.cpp")
create_single_source_cgal_program("region_growing_with_polylines.cpp")
create_single_source_cgal_program("region_growing_on_point_set_2.cpp")
create_single_source_cgal_program("region_growing_on_point_set_3.cpp")
create_single_source_cgal_program("region_growing_on_polygon_mesh.cpp")
# create_single_source_cgal_program("region_growing_on_polyline_3.cpp")
create_single_source_cgal_program("region_growing_with_custom_classes.cpp")
create_single_source_cgal_program("shape_detection_basic_deprecated.cpp")
foreach(
@ -34,16 +30,14 @@ if(TARGET CGAL::Eigen3_support)
efficient_RANSAC_with_callback
efficient_RANSAC_and_plane_regularization
region_growing_basic
region_growing_with_lines
region_growing_with_polylines
region_growing_on_point_set_2
region_growing_on_point_set_3
region_growing_on_polygon_mesh
# region_growing_on_polyline_3
region_growing_with_custom_classes
shape_detection_basic_deprecated)
target_link_libraries(${target} PUBLIC CGAL::Eigen3_support)
endforeach()
endif()
create_single_source_cgal_program("efficient_RANSAC_with_custom_shape.cpp")

View File

@ -4,25 +4,38 @@
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Shape_detection.h>
using Kernel = CGAL::Simple_cartesian<float>;
using Point_3 = typename Kernel::Point_3;
using Kernel = CGAL::Simple_cartesian<double>;
using Point_3 = typename Kernel::Point_3;
using Vector_3 = typename Kernel::Vector_3;
int main() {
const std::vector<Point_3> points = {
Point_3(0, 0, 0), Point_3(1, 0, 0), Point_3(2, 0, 0),
Point_3(3, 0, 0), Point_3(4, 0, 0), Point_3(0, 1, 0),
Point_3(1, 1, 0), Point_3(2, 1, 0), Point_3(3, 1, 0),
Point_3(4, 1, 0), Point_3(0, 2, 0), Point_3(1, 2, 0),
Point_3(2, 2, 0), Point_3(3, 2, 0), Point_3(4, 2, 0)
const std::vector< std::pair<Point_3, Vector_3> > points = {
std::make_pair(Point_3(0.1, 0.0, 0.0), Vector_3(0.1, 0.0, 1.0)),
std::make_pair(Point_3(0.5, 0.0, 0.0), Vector_3(0.5, 0.0, 1.0)),
std::make_pair(Point_3(0.9, 0.0, 0.0), Vector_3(0.9, 0.0, 1.0)),
std::make_pair(Point_3(0.1, 1.0, 0.0), Vector_3(0.1, 1.0, 1.0)),
std::make_pair(Point_3(0.5, 1.0, 0.0), Vector_3(0.5, 1.0, 1.0)),
std::make_pair(Point_3(0.9, 1.0, 0.0), Vector_3(0.9, 1.0, 1.0)),
std::make_pair(Point_3(0.1, 2.0, 0.0), Vector_3(0.1, 2.0, 1.0)),
std::make_pair(Point_3(0.5, 2.0, 0.0), Vector_3(0.5, 2.0, 1.0)),
std::make_pair(Point_3(0.9, 2.0, 0.0), Vector_3(0.9, 2.0, 1.0))
};
std::cout << "* number of input points: " << points.size() << std::endl;
assert(points.size() == 15);
assert(points.size() == 9);
std::vector< std::vector<std::size_t> > regions;
// CGAL::Shape_detection::region_growing_planes(points, std::back_inserter(regions));
std::cout << "* number of found regions: " << regions.size() << std::endl;
CGAL::Shape_detection::region_growing_planes(
points, std::back_inserter(regions), CGAL::parameters::neighbor_radius(1.5));
std::cout << "* number of found planar regions: " << regions.size() << std::endl;
assert(regions.size() == 1);
regions.clear();
// CGAL::Shape_detection::region_growing_lines(
// points, std::back_inserter(regions), CGAL::parameters::neighbor_radius(0.5));
std::cout << "* number of found linear regions: " << regions.size() << std::endl;
assert(regions.size() == 3);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,95 @@
#include "include/utils.h"
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Shape_detection/Region_growing/Region_growing.h>
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_polyline.h>
// Typedefs.
using Kernel = CGAL::Simple_cartesian<double>;
using FT = typename Kernel::FT;
using Point_3 = typename Kernel::Point_3;
using Input_range = std::vector<Point_3>;
using Point_map = CGAL::Identity_property_map<Point_3>;
using Neighbor_query = CGAL::Shape_detection::Polyline::One_ring_neighbor_query<Kernel, Input_range, Point_map>;
using Region_type = CGAL::Shape_detection::Polyline::Least_squares_line_fit_region<Kernel, Input_range, Point_map>;
using Region_growing = CGAL::Shape_detection::Region_growing<Input_range, Neighbor_query, Region_type>;
int main(int argc, char *argv[]) {
// Load polyline data either from a local folder or a user-provided file.
std::ifstream in(argc > 1 ? argv[1] : "data/polyline_3.polylines.txt");
CGAL::set_ascii_mode(in);
if (!in) {
std::cerr << "ERROR: cannot read the input file!" << std::endl;
return EXIT_FAILURE;
}
std::size_t n = std::size_t(-1);
in >> n;
Input_range input_range;
input_range.reserve(n);
while (n--) {
Point_3 point; in >> point;
input_range.push_back(point);
if (!in.good()) {
std::cout << "ERROR: cannot load a polyline!" << std::endl;
return EXIT_FAILURE;
}
}
in.close();
std::cout << "* number of input vertices: " << input_range.size() << std::endl;
assert(input_range.size() == 249);
// Default parameter values for the data file polyline_3.polylines.txt.
const FT max_distance_to_line = FT(45) / FT(10);
const FT max_accepted_angle = FT(45);
const std::size_t min_region_size = 5;
const bool sort_regions = true;
// Create instances of the classes Neighbor_query and Region_type.
Neighbor_query neighbor_query(input_range);
Region_type region_type(
input_range,
CGAL::parameters::
distance_threshold(max_distance_to_line).
angle_deg_threshold(max_accepted_angle).
min_region_size(min_region_size).
sort_regions(sort_regions));
// Create an instance of the region growing class.
Region_growing region_growing(
input_range, neighbor_query, region_type);
// Run the algorithm.
std::vector< std::vector<std::size_t> > regions;
region_growing.detect(std::back_inserter(regions));
std::cout << "* number of found regions: " << regions.size() << std::endl;
assert(regions.size() == 9);
// Sort the output.
if (sort_regions) {
std::sort(regions.begin(), regions.end(),
[&](const std::vector<std::size_t>& r1, const std::vector<std::size_t>& r2) {
// Since all indices within each region are sorted, see the region_type,
// and our input is a polyline, it is enough to sort them by the first index only.
assert(r1.size() >= min_region_size);
assert(r2.size() >= min_region_size);
return r1.front() < r2.front();
});
for (std::size_t i = 0; i < regions.size(); ++i) {
std::cout << "region " << i << ": ";
for (const std::size_t index : regions[i]) {
std::cout << index << " ";
}
std::cout <<std::endl;
}
}
// Save regions to a file.
const std::string fullpath = (argc > 2 ? argv[2] : "regions_polyline_3.ply");
utils::save_point_regions<Kernel, Input_range, Point_map>(
input_range, regions, fullpath);
return EXIT_SUCCESS;
}

View File

@ -25,4 +25,96 @@
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_point_set/Least_squares_line_fit_sorting.h>
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_point_set/Least_squares_plane_fit_sorting.h>
namespace CGAL {
namespace Shape_detection {
template<
typename Point_d,
typename Vector_d,
typename OutputIterator,
typename NamedParameters>
OutputIterator region_growing_lines(
const std::vector< std::pair<Point_d, Vector_d> >& points_with_normals,
OutputIterator regions, const NamedParameters& np) {
using GeomTraits = typename Kernel_traits<Point_d>::Kernel;
using Point_with_normal = std::pair<Point_d, Vector_d>;
using Input_range = std::vector<Point_with_normal>;
using Point_map = CGAL::First_of_pair_property_map<Point_with_normal>;
using Normal_map = CGAL::Second_of_pair_property_map<Point_with_normal>;
using Neighbor_query = Point_set::Sphere_neighbor_query<GeomTraits, Input_range, Point_map>;
using Region_type = Point_set::Least_squares_line_fit_region<GeomTraits, Input_range, Point_map, Normal_map>;
using Sorting = Point_set::Least_squares_line_fit_sorting<GeomTraits, Input_range, Neighbor_query, Point_map>;
using Region_growing = Region_growing<Input_range, Neighbor_query, Region_type, typename Sorting::Seed_map>;
Neighbor_query neighbor_query(points_with_normals, np, Point_map());
Region_type region_type(points_with_normals, np, Point_map(), Normal_map());
Sorting sorting(points_with_normals, neighbor_query, Point_map());
sorting.sort();
Region_growing region_growing(
points_with_normals, neighbor_query, region_type, sorting.seed_map());
region_growing.detect(regions);
return regions;
}
template<
typename Point_d,
typename Vector_d,
typename OutputIterator>
OutputIterator region_growing_lines(
const std::vector< std::pair<Point_d, Vector_d> >& points_with_normals,
OutputIterator regions) {
return region_growing_lines(
points_with_normals, regions, CGAL::parameters::all_default());
}
template<
typename Point_3,
typename Vector_3,
typename OutputIterator,
typename NamedParameters>
OutputIterator region_growing_planes(
const std::vector< std::pair<Point_3, Vector_3> >& points_with_normals,
OutputIterator regions, const NamedParameters& np) {
using GeomTraits = typename Kernel_traits<Point_3>::Kernel;
using Point_with_normal = std::pair<Point_3, Vector_3>;
using Input_range = std::vector<Point_with_normal>;
using Point_map = CGAL::First_of_pair_property_map<Point_with_normal>;
using Normal_map = CGAL::Second_of_pair_property_map<Point_with_normal>;
using Neighbor_query = Point_set::Sphere_neighbor_query<GeomTraits, Input_range, Point_map>;
using Region_type = Point_set::Least_squares_plane_fit_region<GeomTraits, Input_range, Point_map, Normal_map>;
using Sorting = Point_set::Least_squares_plane_fit_sorting<GeomTraits, Input_range, Neighbor_query, Point_map>;
using Region_growing = Region_growing<Input_range, Neighbor_query, Region_type, typename Sorting::Seed_map>;
Neighbor_query neighbor_query(points_with_normals, np, Point_map());
Region_type region_type(points_with_normals, np, Point_map(), Normal_map());
Sorting sorting(points_with_normals, neighbor_query, Point_map());
sorting.sort();
Region_growing region_growing(
points_with_normals, neighbor_query, region_type, sorting.seed_map());
region_growing.detect(regions);
return regions;
}
template<
typename Point_3,
typename Vector_3,
typename OutputIterator>
OutputIterator region_growing_planes(
const std::vector< std::pair<Point_3, Vector_3> >& points_with_normals,
OutputIterator regions) {
return region_growing_planes(
points_with_normals, regions, CGAL::parameters::all_default());
}
} // namespace Shape_detection
} // namespace CGAL
#endif // CGAL_SHAPE_DETECTION_REGION_GROWING_POINT_SET_H

View File

@ -20,4 +20,96 @@
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_polygon_mesh/Least_squares_plane_fit_region.h>
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_polygon_mesh/Least_squares_plane_fit_sorting.h>
namespace CGAL {
namespace Shape_detection {
template<
typename GeomTraits,
typename OutputIterator,
typename NamedParameters>
OutputIterator region_growing_planes(
const CGAL::Polyhedron_3<GeomTraits, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_vector>& polyhedron,
OutputIterator regions, const NamedParameters& np) {
using Polyhedron = CGAL::Polyhedron_3<GeomTraits, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_vector>;
using Face_range = typename CGAL::Iterator_range<typename boost::graph_traits<Polyhedron>::face_iterator>;
using Neighbor_query = Polygon_mesh::One_ring_neighbor_query<Polyhedron, Face_range>;
using Region_type = Polygon_mesh::Least_squares_plane_fit_region<GeomTraits, Polyhedron, Face_range>;
using Sorting = Polygon_mesh::Least_squares_plane_fit_sorting<GeomTraits, Polyhedron, Neighbor_query, Face_range>;
using Vertex_to_point_map = typename Region_type::Vertex_to_point_map;
using Region_growing = Region_growing<Face_range, Neighbor_query, Region_type, typename Sorting::Seed_map>;
const Face_range face_range = faces(polyhedron);
const Vertex_to_point_map vertex_to_point_map(
get(CGAL::vertex_point, polyhedron));
Neighbor_query neighbor_query(polyhedron);
Region_type region_type(polyhedron, np, vertex_to_point_map);
Sorting sorting(polyhedron, neighbor_query, vertex_to_point_map);
sorting.sort();
Region_growing region_growing(
face_range, neighbor_query, region_type, sorting.seed_map());
region_growing.detect(regions);
return regions;
}
template<
typename GeomTraits,
typename OutputIterator>
OutputIterator region_growing_planes(
const CGAL::Polyhedron_3<GeomTraits, CGAL::Polyhedron_items_3, CGAL::HalfedgeDS_vector>& polyhedron,
OutputIterator regions) {
return region_growing_planes(
polyhedron, regions, CGAL::parameters::all_default());
}
template<
typename Point_3,
typename OutputIterator,
typename NamedParameters>
OutputIterator region_growing_planes(
const CGAL::Surface_mesh<Point_3>& surface_mesh,
OutputIterator regions, const NamedParameters& np) {
using GeomTraits = typename Kernel_traits<Point_3>::Kernel;
using Surface_mesh = CGAL::Surface_mesh<Point_3>;
using Face_range = typename Surface_mesh::Face_range;
using Neighbor_query = Polygon_mesh::One_ring_neighbor_query<Surface_mesh>;
using Region_type = Polygon_mesh::Least_squares_plane_fit_region<GeomTraits, Surface_mesh>;
using Sorting = Polygon_mesh::Least_squares_plane_fit_sorting<GeomTraits, Surface_mesh, Neighbor_query>;
using Vertex_to_point_map = typename Region_type::Vertex_to_point_map;
using Region_growing = Region_growing<Face_range, Neighbor_query, Region_type, typename Sorting::Seed_map>;
const Face_range face_range = faces(surface_mesh);
const Vertex_to_point_map vertex_to_point_map(
get(CGAL::vertex_point, surface_mesh));
Neighbor_query neighbor_query(surface_mesh);
Region_type region_type(surface_mesh, np, vertex_to_point_map);
Sorting sorting(surface_mesh, neighbor_query, vertex_to_point_map);
sorting.sort();
Region_growing region_growing(
face_range, neighbor_query, region_type, sorting.seed_map());
region_growing.detect(regions);
return regions;
}
template<
typename Point_3,
typename OutputIterator>
OutputIterator region_growing_planes(
const CGAL::Surface_mesh<Point_3>& surface_mesh, OutputIterator regions) {
return region_growing_planes(
surface_mesh, regions, CGAL::parameters::all_default());
}
} // namespace Shape_detection
} // namespace CGAL
#endif // CGAL_SHAPE_DETECTION_REGION_GROWING_POLYGON_MESH_H

View File

@ -26,6 +26,8 @@
#include <CGAL/boost/graph/Named_function_parameters.h>
// Face graph includes.
#include <CGAL/Iterator_range.h>
#include <CGAL/HalfedgeDS_vector.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/boost/graph/graph_traits_Surface_mesh.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>

View File

@ -20,4 +20,47 @@
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_polyline/Least_squares_line_fit_region.h>
#include <CGAL/Shape_detection/Region_growing/Region_growing_on_polyline/Least_squares_line_fit_sorting.h>
namespace CGAL {
namespace Shape_detection {
template<
typename Point_d,
typename OutputIterator,
typename NamedParameters>
OutputIterator region_growing_polylines(
const std::vector<Point_d>& /* polyline */, OutputIterator regions, const NamedParameters& /* np */) {
// using GeomTraits = typename Kernel_traits<Point_d>::Kernel;
// using Input_range = std::vector<Point_d>;
// using Normal_map = CGAL::Identity_property_map<Point_d>;
// using Neighbor_query = Polyline::One_ring_neighbor_query<GeomTraits, Input_range, Point_map>;
// using Region_type = Polyline::Least_squares_line_fit_region<GeomTraits, Input_range, Point_map>;
// using Sorting = Polyline::Least_squares_line_fit_sorting<GeomTraits, Input_range, Neighbor_query, Point_map>;
// using Region_growing = Region_growing<Input_range, Neighbor_query, Region_type, typename Sorting::Seed_map>;
// Neighbor_query neighbor_query(polyline, np, Point_map());
// Region_type region_type(polyline, np, Point_map());
// Sorting sorting(polyline, neighbor_query, Point_map());
// sorting.sort();
// Region_growing region_growing(
// polyline, neighbor_query, region_type, sorting.seed_map());
// region_growing.detect(regions);
return regions;
}
template<
typename Point_d,
typename OutputIterator>
OutputIterator region_growing_polylines(
const std::vector<Point_d>& polyline, OutputIterator regions) {
return region_growing_polylines(
polyline, regions, CGAL::parameters::all_default());
}
} // namespace Shape_detection
} // namespace CGAL
#endif // CGAL_SHAPE_DETECTION_REGION_GROWING_POLYLINE_H

File diff suppressed because one or more lines are too long