limit each line to 80 characters.

This commit is contained in:
Shihao Wu 2013-07-08 17:09:50 +08:00
parent 273eb39cd2
commit 1ececf54a1
3 changed files with 131 additions and 76 deletions

View File

@ -31,8 +31,9 @@ int main(void)
const unsigned int k = 500; // number of neighbors.
const double neighbor_radius = 0.31; // neighbors size.
const unsigned int iter_number = 30; // number of iterations.
const bool need_compute_density = true; // if needed to compute density to generate more rugularized result,
// especially when the density of input is uneven.
const bool need_compute_density = true; // if needed to compute density to
// generate more rugularized result,
// especially when the density of input is uneven.
// Make room for sample points

View File

@ -94,9 +94,10 @@ public:
/// @return average spacing (scalar).
template < typename Kernel, typename Tree >
typename Kernel::FT
compute_max_spacing(const typename Kernel::Point_3& query, ///< 3D point whose spacing we want to compute
Tree& tree, ///< KD-tree
unsigned int k) ///< number of neighbors
compute_max_spacing
(const typename Kernel::Point_3& query, ///< 3D point
Tree& tree, ///< KD-tree
unsigned int k) ///< number of neighbors
{
// basic geometric types
typedef typename Kernel::FT FT;
@ -122,7 +123,7 @@ compute_max_spacing(const typename Kernel::Point_3& query, ///< 3D point whose s
Point p = search_iterator->first;
double dist2 = CGAL::squared_distance(query,p);
max_distance = dist2 > max_distance ? dist2 : max_distance;// can be simplify, no need to compare..
max_distance = (CGAL::max)(dist2, max_distance);
++search_iterator;
}
@ -147,8 +148,8 @@ compute_average_term(
Tree& tree, ///< KD-tree
unsigned int& k, // nb neighbors
const typename Kernel::FT radius, //accept neighborhood radius
const std::vector<typename Kernel::FT>& density_weight_set //if user need density
//const std::vector<unsigned int>& guess_knn_set//guess knn to spp
const std::vector<typename Kernel::FT>& density_weight_set//if need density
)
{
CGAL_point_set_processing_precondition( k > 1);
@ -253,7 +254,7 @@ compute_repulsion_term(
Tree& tree, ///< KD-tree
const unsigned int k, // nb neighbors
const typename Kernel::FT radius, //accept neighborhood radius
const std::vector<typename Kernel::FT>& density_weight_set //if user need density
const std::vector<typename Kernel::FT>& density_weight_set //if need density
)
{
CGAL_point_set_processing_precondition( k > 1);
@ -515,19 +516,24 @@ guess_KNN_number_for_original_set(
/// \ingroup PkgPointSetProcessing
/// WLOP Algorithm: The simplification algorithm can produces a set of
/// denoised, outlier-free and evenly distributed particles over the original dense point cloud,
/// so as to improve the reliability of current normal orientation algorithm.
/// The core of the algorithm is a Weighted Locally Optimal projection operator with a density uniformization term.
/// More deatail please see: http://web.siat.ac.cn/~huihuang/WLOP/WLOP_page.html
/// denoised, outlier-free and evenly distributed particles over the original
/// dense point cloud, so as to improve the reliability of other algorithms.
///
/// The core of the algorithm is a Weighted Locally Optimal projection operator
/// with a density uniformization term.
/// More deatail please see:http://web.siat.ac.cn/~huihuang/WLOP/WLOP_page.html
///
/// @tparam ForwardIterator iterator over input points.
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = Point_3<Kernel>.
/// It can be omitted if ForwardIterator value_type is convertible to Point_3<Kernel>.
/// @tparam PointPMap is a model of `ReadablePropertyMap`
/// with a value_type = Point_3<Kernel>.
/// It can be omitted if ForwardIterator value_type is convertible to
/// Point_3<Kernel>.
/// @tparam Kernel Geometric traits class.
/// It can be omitted and deduced automatically from PointPMap value_type.
/// It can be omitted and deduced automatically from PointPMap value_type.
///
/// @return iterator of the first point to downsampled points.
// This variant requires all parameters.
template <typename ForwardIterator, typename PointPMap, typename Kernel>
ForwardIterator
@ -538,8 +544,8 @@ regularize_and_simplify_point_set(
double retain_percentage, ///< percentage of points to retain.
unsigned int k, ///< number of neighbors.
const unsigned int iter_number,///< number of iterations.
const bool need_compute_density, ///< if needed to compute density to generate more rugularized result,
/// especially when the density of input is uneven.
const bool need_compute_density, ///< if needed to compute density to
/// generate more rugularized result.
const Kernel& /*kernel*/ ///< geometric traits.
)
{
@ -562,14 +568,16 @@ regularize_and_simplify_point_set(
// to fix: should have at least three distinct points
// but this is costly to check
CGAL_point_set_processing_precondition(first != beyond);
CGAL_point_set_processing_precondition(retain_percentage >= 0 && retain_percentage <= 100);
CGAL_point_set_processing_precondition(retain_percentage >= 0
&& retain_percentage <= 100);
// Random shuffle
std::random_shuffle (first, beyond);
// Computes original(input) and sample points size
std::size_t nb_points_original = std::distance(first, beyond);
std::size_t nb_points_sample = (std::size_t)(FT(nb_points_original) * (retain_percentage/100.0));
std::size_t nb_points_sample = (std::size_t)(FT(nb_points_original) *
(retain_percentage/100.0));
std::size_t first_index_to_sample = nb_points_original - nb_points_sample;
// The first point iter of original and sample points
@ -594,17 +602,22 @@ regularize_and_simplify_point_set(
Point& p0 = get(point_pmap,it);
original_treeElements.push_back(KdTreeElement(p0,i));
}
Tree original_tree(original_treeElements.begin(), original_treeElements.end());
Tree original_tree(original_treeElements.begin(),
original_treeElements.end());
// Guess spacing
FT guess_neighbor_radius = (FT)(std::numeric_limits<double>::max)(); // Or a better max number: (numeric_limits<double>::max)()?
FT guess_neighbor_radius = (FT)(std::numeric_limits<double>::max)();
for(it = first_original_point; it != beyond ; ++it)
{
FT max_spacing = regularize_and_simplify_internal::compute_max_spacing<Kernel,Tree>(get(point_pmap,it),original_tree,k);
guess_neighbor_radius = max_spacing < guess_neighbor_radius ? max_spacing : guess_neighbor_radius;
FT max_spacing = regularize_and_simplify_internal::
compute_max_spacing<Kernel,Tree>
(get(point_pmap,it), original_tree, k);
guess_neighbor_radius = (CGAL::max)(max_spacing, guess_neighbor_radius);
}
guess_neighbor_radius *= 0.95;
std::cout << "Guess Neighborhood Radius:" << guess_neighbor_radius << std::endl;
std::cout << "Guess Neighborhood Radius:"
<< guess_neighbor_radius << std::endl;
// Compute original density weight for original points if user needed
task_timer.start("Compute Density For Original");
@ -613,7 +626,11 @@ regularize_and_simplify_point_set(
{
for (it = first_original_point; it != beyond ; ++it)
{
FT density = regularize_and_simplify_internal::compute_density_weight_for_original_point<Kernel, Tree>(get(point_pmap,it), original_tree, k, guess_neighbor_radius * 0.3);
FT density = regularize_and_simplify_internal::
compute_density_weight_for_original_point<Kernel, Tree>
(get(point_pmap,it), original_tree, k,
guess_neighbor_radius * 0.75);
original_density_weight_set.push_back(density);
}
}
@ -623,7 +640,10 @@ regularize_and_simplify_point_set(
for (i=0 ; i < sample_points.size(); i++)
{
Point& p0 = sample_points[i];
unsigned int guess_knn = regularize_and_simplify_internal::guess_KNN_number_for_original_set<Kernel, Tree>(p0, original_tree, k, guess_neighbor_radius);
unsigned int guess_knn = regularize_and_simplify_internal::
guess_KNN_number_for_original_set<Kernel, Tree>
(p0, original_tree, k, guess_neighbor_radius);
guess_KNN_set.push_back(guess_knn);
}
@ -639,8 +659,6 @@ regularize_and_simplify_point_set(
std::cout << "Compute average term and repulsion term " << endl;
// Initiate a KD-tree search for sample points
unsigned int k_for_sample = 30; // Or it can be conducted by the "guess_neighbor_radius"
for (i=0 ; i < sample_points.size(); i++)
{
Point& p0 = sample_points[i];
@ -655,12 +673,16 @@ regularize_and_simplify_point_set(
{
for (i=0 ; i < sample_points.size(); i++)
{
FT density = regularize_and_simplify_internal::compute_density_weight_for_sample_point<Kernel, Tree>(sample_points[i], sample_tree, k_for_sample, guess_neighbor_radius);
FT density = regularize_and_simplify_internal::
compute_density_weight_for_sample_point<Kernel, Tree>
(sample_points[i], sample_tree,
guess_KNN_set[i], guess_neighbor_radius);
sample_density_weight_set.push_back(density);
}
}
// Compute average term and repulsion term for each sample points separately,
// Compute average term and repulsion term for each sample points ,
// then update each sample points
std::vector<Vector> average_set(nb_points_sample);
std::vector<Vector> repulsion_set(nb_points_sample);
@ -668,14 +690,20 @@ regularize_and_simplify_point_set(
for (i = 0; i < sample_points.size(); i++)
{
Point& p = sample_points[i];
average_set[i] = regularize_and_simplify_internal::compute_average_term<Kernel>(p, original_tree, guess_KNN_set[i], guess_neighbor_radius, original_density_weight_set);
average_set[i] = regularize_and_simplify_internal::
compute_average_term<Kernel>
(p, original_tree, guess_KNN_set[i],
guess_neighbor_radius, original_density_weight_set);
}
//task_timer.start("Compute Repulsion Term");
for (i = 0; i < sample_points.size(); i++)
{
Point& p = sample_points[i];
repulsion_set[i] = regularize_and_simplify_internal::compute_repulsion_term<Kernel>(p, sample_tree, k_for_sample, guess_neighbor_radius, sample_density_weight_set);
repulsion_set[i] = regularize_and_simplify_internal::
compute_repulsion_term<Kernel>
(p, sample_tree, guess_KNN_set[i],
guess_neighbor_radius, sample_density_weight_set);
}
for (i = 0; i < sample_points.size(); i++)
@ -689,7 +717,7 @@ regularize_and_simplify_point_set(
<< (memory>>20) << " Mb allocated" << std::endl;
task_timer.stop();
std::cout << "iterate: " << iter_n + 1 << " "<< std::endl << std::endl;;
std::cout << "iterate: " << iter_n + 1 << " "<< std::endl << std::endl;
}
//Copy back modified sample points to original points for output
@ -714,8 +742,8 @@ regularize_and_simplify_point_set(
double retain_percentage, ///< percentage of points to retain.
unsigned int k, ///< number of neighbors.
const unsigned int iter_number, ///< number of iterations.
const bool need_compute_density ///< if needed to compute density to generate more rugularized result,
/// especially when the density of input is uneven.
const bool need_compute_density ///< if needed to compute density to
/// generate more rugularized result
)
{
typedef typename boost::property_traits<PointPMap>::value_type Point;
@ -741,8 +769,8 @@ regularize_and_simplify_point_set(
double retain_percentage, ///< percentage of points to retain.
unsigned int k, ///< number of neighbors.
const unsigned int iter_number, ///< number of iterations.
const bool need_compute_density ///< if needed to compute density to generate more rugularized result,
/// especially when the density of input is uneven.
const bool need_compute_density ///< if needed to compute density to
/// generate more rugularized result
)
{
return regularize_and_simplify_point_set(

View File

@ -60,9 +60,10 @@ template <typename Kernel>
typename Kernel::Vector_3
compute_average_term(
const typename Kernel::Point_3& query, ///< 3D point to project
const std::vector<rich_grid_internel::Rich_point<Kernel> > neighbor_original_points,
const std::vector<rich_grid_internel::Rich_point<Kernel> >
neighbor_original_points,///< neighbor sample points
const typename Kernel::FT radius, ///<accept neighborhood radius
const std::vector<typename Kernel::FT>& density_weight_set ///<
const std::vector<typename Kernel::FT>& density_weight_set ///< densities
)
{
CGAL_point_set_processing_precondition(radius > 0);
@ -113,9 +114,10 @@ template <typename Kernel>
typename Kernel::Vector_3
compute_repulsion_term(
const typename Kernel::Point_3& query, ///< 3D point to project
const std::vector<rich_grid_internel::Rich_point<Kernel> > neighbor_sample_points, ///< neighbor sample points
const std::vector<rich_grid_internel::Rich_point<Kernel> >
neighbor_sample_points, ///< neighbor sample points
const typename Kernel::FT radius, ///<accept neighborhood radius
const std::vector<typename Kernel::FT>& density_weight_set ///< if user need density
const std::vector<typename Kernel::FT>& density_weight_set ///< densities
)
{
CGAL_point_set_processing_precondition(radius > 0);
@ -174,8 +176,8 @@ template <typename Kernel>
typename Kernel::FT
compute_density_weight_for_original_point(
const typename Kernel::Point_3& query, ///< 3D point to project
const std::vector<typename Kernel::Point_3> neighbor_original_points, ///< neighbor original points
const typename Kernel::FT radius
const std::vector<typename Kernel::Point_3> neighbor_original_points, ///<
const typename Kernel::FT radius ///<accept neighborhood radius
)
{
CGAL_point_set_processing_precondition(radius > 0);
@ -214,7 +216,7 @@ template <typename Kernel>
typename Kernel::FT
compute_density_weight_for_sample_point(
const typename Kernel::Point_3& query, ///< 3D point to project
const std::vector<typename Kernel::Point_3> neighbor_sample_points, ///< neighbor sample points
const std::vector<typename Kernel::Point_3> neighbor_sample_points, ///<
const typename Kernel::FT radius
)
{
@ -250,16 +252,20 @@ compute_density_weight_for_sample_point(
/// \ingroup PkgPointSetProcessing
/// WLOP Algorithm: The simplification algorithm can produces a set of
/// denoised, outlier-free and evenly distributed particles over the original dense point cloud,
/// so as to improve the reliability of current normal orientation algorithm.
/// The core of the algorithm is a Weighted Locally Optimal projection operator with a density uniformization term.
/// More deatail please see: http://web.siat.ac.cn/~huihuang/WLOP/WLOP_page.html
/// denoised, outlier-free and evenly distributed particles over the original
/// dense point cloud, so as to improve the reliability of other algorithms.
///
/// The core of the algorithm is a Weighted Locally Optimal projection operator
/// with a density uniformization term.
/// More deatail please see:http://web.siat.ac.cn/~huihuang/WLOP/WLOP_page.html
///
/// @tparam ForwardIterator iterator over input points.
/// @tparam PointPMap is a model of `ReadablePropertyMap` with a value_type = Point_3<Kernel>.
/// It can be omitted if ForwardIterator value_type is convertible to Point_3<Kernel>.
/// @tparam PointPMap is a model of `ReadablePropertyMap`
/// with a value_type = Point_3<Kernel>.
/// It can be omitted if ForwardIterator value_type is convertible to
/// Point_3<Kernel>.
/// @tparam Kernel Geometric traits class.
/// It can be omitted and deduced automatically from PointPMap value_type.
/// It can be omitted and deduced automatically from PointPMap value_type.
///
/// @return iterator of the first point to downsampled points.
@ -273,8 +279,8 @@ regularize_and_simplify_point_set_using_balltree(
double retain_percentage, ///< percentage of points to retain.
const typename Kernel::FT neighbor_radius, ///< size of neighbors.
const unsigned int iter_number,///< number of iterations.
const bool need_compute_density, ///< if needed to compute density to generate more rugularized result,
/// especially when the density of input is uneven.
const bool need_compute_density, ///< if needed to compute density to
///generate more rugularized result.
const Kernel& /*kernel*/ ///< geometric traits.
)
{
@ -291,14 +297,16 @@ regularize_and_simplify_point_set_using_balltree(
// to fix: should have at least three distinct points
// but this is costly to check
CGAL_point_set_processing_precondition(first != beyond);
CGAL_point_set_processing_precondition(retain_percentage >= 0 && retain_percentage <= 100);
CGAL_point_set_processing_precondition(retain_percentage >= 0 &&
retain_percentage <= 100);
// Random shuffle
std::random_shuffle (first, beyond);
// Computes original(input) and sample points size
std::size_t nb_points_original = std::distance(first, beyond);
std::size_t nb_points_sample = (std::size_t)(FT(nb_points_original) * (retain_percentage/100.0));
std::size_t nb_points_sample = (std::size_t)(FT(nb_points_original) *
(retain_percentage/100.0));
std::size_t first_index_to_sample = nb_points_original - nb_points_sample;
// The first point iter of original and sample points
@ -339,19 +347,23 @@ regularize_and_simplify_point_set_using_balltree(
task_timer.start();
std::cout << "Initialization / Compute Density For Original" << std::endl;
rich_grid_internel::compute_ball_neighbors_one_self(original_rich_point_set, box, neighbor_radius);
rich_grid_internel::compute_ball_neighbors_one_self(original_rich_point_set
, box, neighbor_radius);
for (it = first_original_point, i = 0; it != beyond ; ++it, i++)
{
std::vector<Point> original_neighbors;
std::vector<unsigned int>& neighors_indexes = original_rich_point_set[i].neighbors;
std::vector<unsigned int>& neighors_indexes =
original_rich_point_set[i].neighbors;
for (unsigned int j = 0; j < neighors_indexes.size(); j++)
{
original_neighbors.push_back(original_points[neighors_indexes[j]]);
}
FT density = regularize_and_simplify_internal::compute_density_weight_for_original_point<Kernel>(get(point_pmap,it),
original_neighbors, neighbor_radius);
FT density = regularize_and_simplify_internal::
compute_density_weight_for_original_point<Kernel>(
get(point_pmap,it),
original_neighbors, neighbor_radius);
original_density_weight_set.push_back(density);
original_rich_point_set[i].neighbors.clear();
@ -376,7 +388,8 @@ regularize_and_simplify_point_set_using_balltree(
Rich_point rp(p0, i);
sample_rich_point_set[i] = rp;
}
rich_grid_internel::compute_ball_neighbors_one_self(sample_rich_point_set, box, neighbor_radius);
rich_grid_internel::compute_ball_neighbors_one_self(sample_rich_point_set,
box, neighbor_radius);
// Compute sample density weight for sample points if user needed
std::vector<FT> sample_density_weight_set;
@ -385,23 +398,28 @@ regularize_and_simplify_point_set_using_balltree(
for (i=0 ; i < sample_points.size(); i++)
{
std::vector<Point> sample_neighbors;
std::vector<unsigned int>& neighors_indexes = sample_rich_point_set[i].neighbors;
std::vector<unsigned int>& neighors_indexes =
sample_rich_point_set[i].neighbors;
for (unsigned int j = 0; j < neighors_indexes.size(); j++)
{
sample_neighbors.push_back(sample_points[neighors_indexes[j]]);
}
FT density = regularize_and_simplify_internal::compute_density_weight_for_sample_point<Kernel>
(sample_points[i], sample_neighbors, neighbor_radius);
FT density = regularize_and_simplify_internal::
compute_density_weight_for_sample_point<Kernel>
(sample_points[i], sample_neighbors, neighbor_radius);
sample_density_weight_set.push_back(density);
}
}
// Build Ball Tree For Sample-Original Neighbor
rich_grid_internel::compute_ball_neighbors_one_to_another(sample_rich_point_set,
original_rich_point_set, box, neighbor_radius);
rich_grid_internel::compute_ball_neighbors_one_to_another
(sample_rich_point_set,
original_rich_point_set, box, neighbor_radius);
// Compute average term and repulsion term for each sample points separately,
// Compute average term and repulsion term for each sample points,
// then update each sample points
std::vector<Vector> average_set(nb_points_sample);
std::vector<Vector> repulsion_set(nb_points_sample);
@ -411,7 +429,8 @@ regularize_and_simplify_point_set_using_balltree(
{
Point& p = sample_points[i];
std::vector<Rich_point> rich_original_neighbors;
std::vector<unsigned int>& neighors_indexes = sample_rich_point_set[i].original_neighbors;
std::vector<unsigned int>& neighors_indexes =
sample_rich_point_set[i].original_neighbors;
if (neighors_indexes.empty())
{
@ -426,14 +445,18 @@ regularize_and_simplify_point_set_using_balltree(
rich_original_neighbors.push_back(rp);
}
average_set[i] = regularize_and_simplify_internal::compute_average_term<Kernel>(p, rich_original_neighbors, neighbor_radius, original_density_weight_set);
average_set[i] = regularize_and_simplify_internal::
compute_average_term<Kernel>
(p, rich_original_neighbors, neighbor_radius,
original_density_weight_set);
}
//repulsion term
for (i = 0; i < sample_points.size(); i++)
{
std::vector<Rich_point> rich_sample_neighbors;
std::vector<unsigned int>& neighors_indexes = sample_rich_point_set[i].neighbors;
std::vector<unsigned int>& neighors_indexes =
sample_rich_point_set[i].neighbors;
if (neighors_indexes.empty())
{
@ -449,7 +472,10 @@ regularize_and_simplify_point_set_using_balltree(
}
Point& p = sample_points[i];
repulsion_set[i] = regularize_and_simplify_internal::compute_repulsion_term<Kernel>(p, rich_sample_neighbors, neighbor_radius, sample_density_weight_set);
repulsion_set[i] = regularize_and_simplify_internal::
compute_repulsion_term<Kernel>
(p, rich_sample_neighbors, neighbor_radius,
sample_density_weight_set);
}
// update points positions according to average and repulsion term
@ -464,7 +490,7 @@ regularize_and_simplify_point_set_using_balltree(
<< (memory>>20) << " Mb allocated" << std::endl;
task_timer.stop();
std::cout << "iterate: " << iter_n + 1 << " "<< std::endl << std::endl;;
std::cout << "iterate: " << iter_n + 1 << " "<< std::endl << std::endl;
}
//Copy back modified sample points to original points for output
@ -489,8 +515,8 @@ regularize_and_simplify_point_set_using_balltree(
double retain_percentage, ///< percentage of points to retain
double neighbor_radius, ///< size of neighbors.
const unsigned int iter_number, ///< number of iterations.
const bool need_compute_density ///< if needed to compute density to generate more rugularized result,
/// especially when the density of input is uneven.
const bool need_compute_density ///< if needed to compute density
/// to generate more rugularized result.
)
{
typedef typename boost::property_traits<PointPMap>::value_type Point;
@ -516,8 +542,8 @@ regularize_and_simplify_point_set_using_balltree(
double retain_percentage, ///< percentage of points to retain
double neighbor_radius, ///< size of neighbors.
const unsigned int iter_number, ///< number of iterations.
const bool need_compute_density ///< if needed to compute density to generate more rugularized result,
/// especially when the density of input is uneven.
const bool need_compute_density ///< if needed to compute density to generate
/// more rugularized result.
)
{
return regularize_and_simplify_point_set_using_balltree(