mirror of https://github.com/CGAL/cgal
Define fullScore method outside octree
This commit is contained in:
parent
0e305fc8a9
commit
0baee2d8fb
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue