mirror of https://github.com/CGAL/cgal
added support for GenericDescriptorOutlierFilter to the CGAL libpointmatcher interface
This commit is contained in:
parent
9e1a4e7037
commit
c8307dc0d6
|
|
@ -435,6 +435,30 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
|
|||
> ::type type;
|
||||
};
|
||||
|
||||
template<typename PointRange, typename NamedParameters>
|
||||
class GetScalarMap
|
||||
{
|
||||
struct DummyScalarMap
|
||||
{
|
||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type key_type;
|
||||
typedef typename GetK<PointRange, NamedParameters>::Kernel::FT value_type;
|
||||
typedef value_type reference;
|
||||
typedef boost::read_write_property_map_tag category;
|
||||
|
||||
typedef DummyScalarMap Self;
|
||||
friend reference get(const Self&, const key_type&) { return value_type(1); }
|
||||
friend void put(const Self&, const key_type&, const value_type&) { }
|
||||
};
|
||||
|
||||
public:
|
||||
typedef DummyScalarMap NoMap;
|
||||
typedef typename internal_np::Lookup_named_param_def <
|
||||
internal_np::scalar_t,
|
||||
NamedParameters,
|
||||
DummyScalarMap // default
|
||||
> ::type type;
|
||||
};
|
||||
|
||||
template<typename PlaneRange, typename NamedParameters>
|
||||
class GetPlaneMap
|
||||
{
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ CGAL_add_named_parameter(pointmatcher_config_t, pointmatcher_config, pointmatche
|
|||
CGAL_add_named_parameter(adjacencies_t, adjacencies, adjacencies)
|
||||
CGAL_add_named_parameter(scan_angle_t, scan_angle_map, scan_angle_map)
|
||||
CGAL_add_named_parameter(scanline_id_t, scanline_id_map, scanline_id_map)
|
||||
CGAL_add_named_parameter(scalar_t, scalar_map, scalar_map)
|
||||
|
||||
// List of named parameters used in Surface_mesh_approximation package
|
||||
CGAL_add_named_parameter(verbose_level_t, verbose_level, verbose_level)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,17 @@ typedef std::pair<Point_3, Vector_3> Pwn;
|
|||
typedef CGAL::First_of_pair_property_map<Pwn> Point_map;
|
||||
typedef CGAL::Second_of_pair_property_map<Pwn> Normal_map;
|
||||
|
||||
struct Weight_map
|
||||
{
|
||||
typedef Pwn key_type;
|
||||
typedef typename K::FT value_type;
|
||||
typedef value_type reference;
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
typedef Weight_map Self;
|
||||
friend reference get(const Self&, const key_type&) { return value_type(1); }
|
||||
};
|
||||
|
||||
namespace params = CGAL::parameters;
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
|
|
@ -63,12 +74,13 @@ int main(int argc, const char** argv)
|
|||
point_set_2_filters.push_back( ICP_config { /*.name=*/"MinDistDataPointsFilter" , /*.params=*/{ {"minDist", "0.5" }} } );
|
||||
point_set_2_filters.push_back( ICP_config { /*.name=*/"RandomSamplingDataPointsFilter", /*.params=*/{ {"prob" , "0.05"}} } );
|
||||
|
||||
// Prepare matcher function
|
||||
// Prepare matcher function
|
||||
ICP_config matcher { /*.name=*/"KDTreeMatcher", /*.params=*/{ {"knn", "1"}, {"epsilon", "3.16"} } };
|
||||
|
||||
// Prepare outlier filters
|
||||
std::vector<ICP_config> outlier_filters;
|
||||
outlier_filters.push_back( ICP_config { /*.name=*/"TrimmedDistOutlierFilter", /*.params=*/{ {"ratio", "0.75" }} } );
|
||||
outlier_filters.push_back( ICP_config { /*.name=*/"GenericDescriptorOutlierFilter", /*.params=*/{ {"descName", "weights" }} } );
|
||||
|
||||
// Prepare error minimizer
|
||||
ICP_config error_minimizer { /*.name=*/"PointToPointErrorMinimizer"};
|
||||
|
|
@ -92,7 +104,7 @@ int main(int argc, const char** argv)
|
|||
std::pair<K::Aff_transformation_3, bool> res =
|
||||
CGAL::pointmatcher::compute_registration_transformation
|
||||
(pwns1, pwns2,
|
||||
params::point_map(Point_map()).normal_map(Normal_map())
|
||||
params::point_map(Point_map()).normal_map(Normal_map()).scalar_map(Weight_map())
|
||||
.point_set_filters(point_set_1_filters)
|
||||
.matcher(matcher)
|
||||
.outlier_filters(outlier_filters)
|
||||
|
|
@ -100,7 +112,7 @@ int main(int argc, const char** argv)
|
|||
.transformation_checkers(transformation_checkers)
|
||||
.inspector(inspector)
|
||||
.logger(logger),
|
||||
params::point_map(Point_map()).normal_map(Normal_map())
|
||||
params::point_map(Point_map()).normal_map(Normal_map()).scalar_map(Weight_map())
|
||||
.point_set_filters(point_set_2_filters)
|
||||
.transformation(identity_transform) /* initial transform for pwns2.
|
||||
* default value is already identity transform.
|
||||
|
|
|
|||
|
|
@ -220,10 +220,11 @@ template<typename Scalar,
|
|||
typename PointRange,
|
||||
typename PointMap,
|
||||
typename VectorMap,
|
||||
typename ScalarMap,
|
||||
typename PM_matrix>
|
||||
void
|
||||
copy_cgal_points_to_pm_matrix
|
||||
(const PointRange& prange, PointMap point_map, VectorMap vector_map, PM_matrix& pm_points, PM_matrix& pm_normals)
|
||||
(const PointRange& prange, PointMap point_map, VectorMap vector_map, ScalarMap scalar_map, PM_matrix& pm_points, PM_matrix& pm_normals, PM_matrix& pm_weights)
|
||||
{
|
||||
int idx = 0;
|
||||
for(const auto& p : prange)
|
||||
|
|
@ -236,11 +237,15 @@ copy_cgal_points_to_pm_matrix
|
|||
pm_points(3, idx) = Scalar(1.);
|
||||
|
||||
// normal
|
||||
const auto& normal = get (vector_map, p);
|
||||
const auto& normal = get(vector_map, p);
|
||||
pm_normals(0, idx) = normal.x();
|
||||
pm_normals(1, idx) = normal.y();
|
||||
pm_normals(2, idx) = normal.z();
|
||||
|
||||
// weight
|
||||
const auto& weight = get(scalar_map, p);
|
||||
pm_weights(0, idx) = weight;
|
||||
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
|
|
@ -251,11 +256,14 @@ template <class Kernel,
|
|||
class PointMap1,
|
||||
class PointMap2,
|
||||
class VectorMap1,
|
||||
class VectorMap2>
|
||||
class VectorMap2,
|
||||
class ScalarMap1,
|
||||
class ScalarMap2>
|
||||
std::pair<typename Kernel::Aff_transformation_3, bool>
|
||||
compute_registration_transformation(const PointRange1& range1, const PointRange2& range2,
|
||||
PointMap1 point_map1, PointMap2 point_map2,
|
||||
VectorMap1 vector_map1, VectorMap2 vector_map2,
|
||||
ScalarMap1 scalar_map1, ScalarMap2 scalar_map2,
|
||||
const typename Kernel::Aff_transformation_3& initial_transform,
|
||||
ICP<typename Kernel::FT> icp)
|
||||
{
|
||||
|
|
@ -273,8 +281,10 @@ compute_registration_transformation(const PointRange1& range1, const PointRange2
|
|||
|
||||
PM_matrix ref_points_pos_matrix = PM_matrix (4, nb_ref_points);
|
||||
PM_matrix ref_points_normal_matrix = PM_matrix (3, nb_ref_points);
|
||||
PM_matrix ref_points_weight_matrix = PM_matrix (1, nb_ref_points);
|
||||
PM_matrix points_pos_matrix = PM_matrix (4, nb_points);
|
||||
PM_matrix points_normal_matrix = PM_matrix (3, nb_points);
|
||||
PM_matrix points_weight_matrix = PM_matrix (1, nb_points);
|
||||
|
||||
// In CGAL, point_set_1 is the reference while point_set_2 is the data
|
||||
|
||||
|
|
@ -282,16 +292,20 @@ compute_registration_transformation(const PointRange1& range1, const PointRange2
|
|||
internal::copy_cgal_points_to_pm_matrix<Scalar>(range1,
|
||||
point_map1,
|
||||
vector_map1,
|
||||
scalar_map1,
|
||||
ref_points_pos_matrix, // out
|
||||
ref_points_normal_matrix); // out
|
||||
ref_points_normal_matrix, // out
|
||||
ref_points_weight_matrix); // out
|
||||
|
||||
internal::copy_cgal_points_to_pm_matrix<Scalar>(range2,
|
||||
point_map2,
|
||||
vector_map2,
|
||||
scalar_map2,
|
||||
points_pos_matrix, // out
|
||||
points_normal_matrix); // out
|
||||
points_normal_matrix, // out
|
||||
points_weight_matrix); // out
|
||||
|
||||
auto construct_PM_cloud = [](const PM_matrix& positions, const PM_matrix& normals) -> PM_cloud
|
||||
auto construct_PM_cloud = [](const PM_matrix& positions, const PM_matrix& normals, const PM_matrix& weights) -> PM_cloud
|
||||
{
|
||||
PM_cloud cloud;
|
||||
|
||||
|
|
@ -300,12 +314,13 @@ compute_registration_transformation(const PointRange1& range1, const PointRange2
|
|||
cloud.addFeature("z", positions.row(2));
|
||||
cloud.addFeature("pad", positions.row(3));
|
||||
cloud.addDescriptor("normals", normals);
|
||||
cloud.addDescriptor("weights", weights);
|
||||
|
||||
return cloud;
|
||||
};
|
||||
|
||||
PM_cloud ref_cloud = construct_PM_cloud(ref_points_pos_matrix, ref_points_normal_matrix);
|
||||
PM_cloud cloud = construct_PM_cloud(points_pos_matrix, points_normal_matrix);
|
||||
PM_cloud ref_cloud = construct_PM_cloud(ref_points_pos_matrix, ref_points_normal_matrix, ref_points_weight_matrix);
|
||||
PM_cloud cloud = construct_PM_cloud(points_pos_matrix, points_normal_matrix, points_weight_matrix);
|
||||
|
||||
PM_transform_params pm_transform_params = PM_transform_params::Identity(4,4);
|
||||
|
||||
|
|
@ -385,6 +400,12 @@ compute_registration_transformation(const PointRange1& range1, const PointRange2
|
|||
of the iterator of `PointRange1` and whose value type is `geom_traits::Vector_3`}
|
||||
\cgalParamNEnd
|
||||
|
||||
\cgalParamNBegin{scalar_map}
|
||||
\cgalParamDescription{a property map associating 1D values - scalars to the elements of the point set `point_set_1`}
|
||||
\cgalParamType{a model of `ReadablePropertyMap` whose key type is the value type
|
||||
of the iterator of `PointRange1` and whose value type is `geom_traits::FT`}
|
||||
\cgalParamNEnd
|
||||
|
||||
\cgalParamNBegin{point_set_filters}
|
||||
\cgalParamDescription{a chain of filters to be applied to the point set}
|
||||
\cgalParamType{a class model of `Range`. The value type of its iterator must be `ICP_config`.}
|
||||
|
|
@ -510,6 +531,12 @@ compute_registration_transformation(const PointRange1& range1, const PointRange2
|
|||
of the iterator of `PointRange2` and whose value type is `geom_traits::Vector_3`}
|
||||
\cgalParamNEnd
|
||||
|
||||
\cgalParamNBegin{scalar_map}
|
||||
\cgalParamDescription{a property map associating 1D values - scalars to the elements of the point set `point_set_2`}
|
||||
\cgalParamType{a model of `ReadablePropertyMap` whose key type is the value type
|
||||
of the iterator of `PointRange2` and whose value type is `geom_traits::FT`}
|
||||
\cgalParamNEnd
|
||||
|
||||
\cgalParamNBegin{point_set_filters}
|
||||
\cgalParamDescription{a chain of filters to be applied to the point set}
|
||||
\cgalParamType{a class model of `Range`. The value type of its iterator must be `ICP_config`.}
|
||||
|
|
@ -576,14 +603,22 @@ compute_registration_transformation (const PointRange1& point_set_1, const Point
|
|||
typename boost::property_traits<NormalMap2>::value_type> ::value),
|
||||
"The vector type of input ranges must be the same");
|
||||
|
||||
typedef typename PSP::GetScalarMap<PointRange1, NamedParameters1>::type WeightMap1;
|
||||
typedef typename PSP::GetScalarMap<PointRange2, NamedParameters2>::type WeightMap2;
|
||||
CGAL_static_assertion_msg((boost::is_same< typename boost::property_traits<WeightMap1>::value_type,
|
||||
typename boost::property_traits<WeightMap2>::value_type> ::value),
|
||||
"The scalar type of input ranges must be the same");
|
||||
|
||||
typedef typename PSP::GetK<PointRange1, NamedParameters1>::Kernel Kernel;
|
||||
typedef typename Kernel::FT Scalar;
|
||||
typedef typename Kernel::Aff_transformation_3 Transformation;
|
||||
|
||||
PointMap1 point_map1 = choose_parameter(get_parameter(np1, internal_np::point_map), PointMap1());
|
||||
NormalMap1 normal_map1 = choose_parameter(get_parameter(np1, internal_np::normal_map), NormalMap1());
|
||||
WeightMap1 weight_map1 = choose_parameter(get_parameter(np1, internal_np::scalar_map), WeightMap1());
|
||||
PointMap2 point_map2 = choose_parameter(get_parameter(np2, internal_np::point_map), PointMap2());
|
||||
NormalMap2 normal_map2 = choose_parameter(get_parameter(np2, internal_np::normal_map), NormalMap2());
|
||||
WeightMap2 weight_map2 = choose_parameter(get_parameter(np2, internal_np::scalar_map), WeightMap2());
|
||||
|
||||
// initial transformation
|
||||
Transformation initial_transformation
|
||||
|
|
@ -592,6 +627,7 @@ compute_registration_transformation (const PointRange1& point_set_1, const Point
|
|||
return internal::compute_registration_transformation<Kernel>(point_set_1, point_set_2,
|
||||
point_map1, point_map2,
|
||||
normal_map1, normal_map2,
|
||||
weight_map1, weight_map2,
|
||||
initial_transformation,
|
||||
internal::construct_icp<Scalar>(np1, np2));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue