Define fullScore method outside octree

This commit is contained in:
Jackson Campolattaro 2020-07-23 11:09:55 -04:00
parent 0e305fc8a9
commit 0baee2d8fb
1 changed files with 937 additions and 878 deletions

View File

@ -63,6 +63,7 @@ namespace CGAL {
/// \cond SKIP_IN_MANUAL
struct Filter_unassigned_points {
Filter_unassigned_points() : m_shape_index(dummy) {}
Filter_unassigned_points(const std::vector<int> &shapeIndex)
: m_shape_index(shapeIndex) {}
@ -71,6 +72,7 @@ namespace CGAL {
return m_shape_index[x] == -1;
else return true; // to prevent infinite incrementing
}
const std::vector<int> &m_shape_index;
std::vector<int> dummy;
};
@ -106,6 +108,7 @@ namespace CGAL {
typedef unspecified_type Plane_range;
///< `Iterator_range` with a bidirectional constant iterator type with value type `boost::shared_ptr<Plane_shape>`.
#else
struct Shape_range : public Iterator_range<
typename std::vector<boost::shared_ptr<Shape> >::const_iterator> {
typedef Iterator_range<
@ -114,6 +117,7 @@ namespace CGAL {
Shape_range(boost::shared_ptr<std::vector<boost::shared_ptr<Shape> > >
extracted_shapes) : Base(make_range(extracted_shapes->begin(),
extracted_shapes->end())), m_extracted_shapes(extracted_shapes) {}
private:
boost::shared_ptr<std::vector<boost::shared_ptr<Shape> > >
m_extracted_shapes; // keeps a reference to the shape vector
@ -127,10 +131,12 @@ namespace CGAL {
Plane_range(boost::shared_ptr<std::vector<boost::shared_ptr<Plane_shape> > >
extracted_shapes) : Base(make_range(extracted_shapes->begin(),
extracted_shapes->end())), m_extracted_shapes(extracted_shapes) {}
private:
boost::shared_ptr<std::vector<boost::shared_ptr<Plane_shape> > >
m_extracted_shapes; // keeps a reference to the shape vector
};
#endif
#ifdef DOXYGEN_RUNNING
@ -154,12 +160,8 @@ namespace CGAL {
*/
struct Parameters {
Parameters()
: probability((FT) 0.01)
, min_points((std::numeric_limits<std::size_t>::max)())
, epsilon(-1)
, normal_threshold((FT) 0.9)
, cluster_epsilon(-1)
{}
: probability((FT) 0.01), min_points((std::numeric_limits<std::size_t>::max)()), epsilon(-1),
normal_threshold((FT) 0.9), cluster_epsilon(-1) {}
/*!
Probability to control search endurance.
@ -230,14 +232,8 @@ namespace CGAL {
Constructs an empty shape detection object.
*/
Efficient_RANSAC(Traits t = Traits())
: m_traits(t)
, m_direct_octrees(nullptr)
, m_global_octree(nullptr)
, m_num_subsets(0)
, m_num_available_points(0)
, m_num_total_points(0)
, m_valid_iterators(false)
{}
: m_traits(t), m_direct_octrees(nullptr), m_global_octree(nullptr), m_num_subsets(0),
m_num_available_points(0), m_num_total_points(0), m_valid_iterators(false) {}
/*!
Releases all memory allocated by this instance including shapes.
@ -250,8 +246,7 @@ namespace CGAL {
Retrieves the traits class.
*/
const Traits &
traits() const
{
traits() const {
return m_traits;
}
@ -265,12 +260,11 @@ namespace CGAL {
*/
const Normal_map &normal() const { return m_normal_pmap; }
Input_iterator input_iterator_first() const
{
Input_iterator input_iterator_first() const {
return m_input_iterator_first;
}
Input_iterator input_iterator_beyond() const
{
Input_iterator input_iterator_beyond() const {
return m_input_iterator_beyond;
}
@ -304,6 +298,7 @@ namespace CGAL {
m_valid_iterators = true;
}
/*!
Registers the shape type `ShapeType` in the detection engine that must inherit from `Shape_base`.
For example, for registering a plane as detectable shape, you should call
@ -329,7 +324,8 @@ namespace CGAL {
// Generation of subsets
m_num_subsets = (std::size_t) (std::max<std::ptrdiff_t>)((std::ptrdiff_t)
std::floor(std::log(double(m_num_total_points))/std::log(2.))-9, 2);
std::floor(std::log(double(m_num_total_points)) /
std::log(2.)) - 9, 2);
// SUBSET GENERATION ->
// approach with increasing subset sizes -> replace with octree later on
@ -365,8 +361,7 @@ namespace CGAL {
last + subsetSize + 1,
m_point_pmap, m_normal_pmap,
remainingPoints - subsetSize);
}
else
} else
m_direct_octrees[0] = new Direct_octree(
m_traits, m_input_iterator_first,
m_input_iterator_first + (subsetSize),
@ -468,8 +463,7 @@ namespace CGAL {
*/
bool detect(const Parameters &options = Parameters(),
const std::function<bool(double)> &callback
= std::function<bool(double)>())
{
= std::function<bool(double)>()) {
m_options = options;
// No shape types for detection or no points provided, exit
@ -602,20 +596,17 @@ namespace CGAL {
best_expected = p->expected_value();
candidates.push_back(p);
}
else {
} else {
failed_candidates++;
delete p;
}
}
else {
} else {
failed_candidates++;
delete p;
}
}
if (failed_candidates >= limit_failed_candidates)
{
if (failed_candidates >= limit_failed_candidates) {
force_exit = true;
}
@ -673,8 +664,7 @@ namespace CGAL {
return false;
// check score against min_points and clear out candidates if too low
if (best_candidate->indices_of_assigned_points().size() <
m_options.min_points)
{
m_options.min_points) {
if (!(best_candidate->indices_of_assigned_points().empty()))
for (std::size_t i = 0; i < candidates.size() - 1; i++) {
if (best_candidate->is_same(candidates[i])) {
@ -716,9 +706,7 @@ namespace CGAL {
if (callback && !callback(num_invalid / double(m_num_total_points)))
return false;
}
else
if (stop_probability((std::size_t) best_candidate->expected_value(),
} else if (stop_probability((std::size_t) best_candidate->expected_value(),
(m_num_available_points - num_invalid),
generated_candidates,
m_global_octree->maxLevel())
@ -789,8 +777,7 @@ namespace CGAL {
if (candidates[i]->max_bound() < m_options.min_points) {
delete candidates[i];
candidates[i] = nullptr;
}
else {
} else {
best_expected = (candidates[i]->expected_value() > best_expected) ?
candidates[i]->expected_value() : best_expected;
}
@ -815,8 +802,7 @@ namespace CGAL {
if (candidates[end]) end++;
candidates.resize(end);
}
else if (!keep_searching)
} else if (!keep_searching)
++generated_candidates;
if (callback && !callback(num_invalid / double(m_num_total_points)))
@ -827,8 +813,7 @@ namespace CGAL {
generated_candidates,
m_global_octree->maxLevel())
> m_options.probability);
}
while((keep_searching
} while ((keep_searching
&& FT(m_num_available_points - num_invalid) >= m_options.min_points)
|| best_expected >= m_options.min_points);
@ -868,8 +853,7 @@ namespace CGAL {
boost::shared_ptr<std::vector<boost::shared_ptr<Plane_shape> > > planes
= boost::make_shared<std::vector<boost::shared_ptr<Plane_shape> > >();
for (std::size_t i = 0; i < m_extracted_shapes->size(); ++ i)
{
for (std::size_t i = 0; i < m_extracted_shapes->size(); ++i) {
boost::shared_ptr<Plane_shape> pshape
= boost::dynamic_pointer_cast<Plane_shape>((*m_extracted_shapes)[i]);
@ -1018,10 +1002,83 @@ namespace CGAL {
return true;
}
inline FT stop_probability(std::size_t largest_candidate, std::size_t num_pts, std::size_t num_candidates, std::size_t octree_depth) const {
return (std::min<FT>)(std::pow((FT) 1.f - (FT) largest_candidate / FT(num_pts * octree_depth * 4), (int) num_candidates), (FT) 1);
inline FT stop_probability(std::size_t largest_candidate, std::size_t num_pts, std::size_t num_candidates,
std::size_t octree_depth) const {
return (std::min<FT>)(
std::pow((FT) 1.f - (FT) largest_candidate / FT(num_pts * octree_depth * 4), (int) num_candidates), (FT) 1);
}
// TODO: Make these work outside the octree!
template<class PointAccessor>
std::size_t fullScore(internal::Octree<PointAccessor> octree, Shape *candidate,
std::vector<int> &shapeIndex,
FT epsilon,
FT normal_threshold) {
std::vector<std::size_t> indices(octree.m_root->size());
for (std::size_t i = 0; i < octree.m_root->size(); i++) {
indices[i] = index(octree.m_root->first + i);
}
candidate->cost_function(this->begin() + octree.m_root->first,
this->begin() + octree.m_root->last,
shapeIndex,
epsilon,
normal_threshold,
indices);
return candidate->m_indices.size();
}
// std::size_t score(Shape *candidate,
// std::vector<int> &shapeIndex,
// FT epsilon,
// FT normal_threshold) {
//
// std::stack<Cell *> stack;
// stack.push(m_root);
//
// while(!stack.empty()) {
// Cell *cell = stack.top();
// stack.pop();
//
// FT width = m_width / (1<<(cell->level));
//
// FT diag = CGAL::sqrt(FT(3) * width * width) + epsilon;
//
// FT dist = candidate->squared_distance(cell->center);
//
// if (dist > (diag * diag))
// continue;
//
// // differ between full or partial overlap?
// // if full overlap further traversal of this branch is not necessary
// if (cell->isLeaf()) {
// std::vector<std::size_t> indices;
// indices.reserve(cell->size());
// for (std::size_t i = 0;i<cell->size();i++) {
// if (shapeIndex[this->index(cell->first + i)] == -1) {
// indices.push_back(this->index(cell->first + i));
// }
// }
//
// candidate->cost_function(epsilon,
// normal_threshold,
// indices);
// }
// else {
// for (std::size_t i = 0;i<8;i++)
// if (cell->child[i])
// stack.push(cell->child[i]);
// }
//
// }
//
// return candidate->m_indices.size();
// }
private:
Parameters m_options;
@ -1053,6 +1110,8 @@ namespace CGAL {
Point_map m_point_pmap;
Normal_map m_normal_pmap;
};
}
}