Rework reference manual

This commit is contained in:
Simon Giraudot 2017-01-06 15:25:43 +01:00
parent 4b543bde97
commit dceddbe418
8 changed files with 430 additions and 431 deletions

View File

@ -60,13 +60,14 @@ public:
/*!
\brief Returns `abstract_attribute` and should be overloaded
by a inherited class with a specific name.
by an inherited class with a specific name.
*/
virtual std::string name() { return "abstract_attribute"; }
/*!
\brief Returns the value taken by the attribute at the given
index. This method must be implemented by inherited classes.
\brief Returns the value taken by the attribute for at the item at
position `index`. This method must be implemented by inherited
classes.
*/
virtual double value (std::size_t index) = 0;
@ -106,7 +107,7 @@ public:
/*!
\ingroup PkgClassification
\brief Handle to a classification `Attribute_base`.
\brief Handle to an `Attribute_base`.
\cgalModels Handle
*/

View File

@ -63,9 +63,9 @@ public:
on a local neighborhood.
\tparam NeighborQuery model of `NeighborQuery`
\param input Input range.
\param input input range.
\param point_map property map to access the input points
\param neighbor_query object used to access neighborhoods of points
\param neighbor_query object used to access neighborhoods of points.
*/
template <typename NeighborQuery>
Local_eigen_analysis (const Range& input,
@ -99,22 +99,22 @@ public:
}
/*!
\brief Returns the estimated unoriented normal vector of the indexed point.
\brief Returns the estimated unoriented normal vector of the point at position `index`.
*/
const Vector& normal_vector (std::size_t index) const { return m_smallest_eigenvectors[index]; }
/*!
\brief Returns the estimated local tangent plane of the index point.
\brief Returns the estimated local tangent plane of the point at position `index`.
*/
Plane plane (std::size_t index) const { return Plane (m_centroids[index], m_smallest_eigenvectors[index]); }
/*!
\brief Returns the normalized eigenvalues of the index point.
\brief Returns the normalized eigenvalues of the point at position `index`.
*/
const Eigenvalues& eigenvalue (std::size_t index) const { return m_eigenvalues[index]; }
/*!
\brief Returns the sum of eigenvalues of the index point.
\brief Returns the sum of eigenvalues of the point at position `index`.
*/
const double& sum_of_eigenvalues (std::size_t index) const { return m_sum_eigenvalues[index]; }

View File

@ -14,10 +14,10 @@ namespace Classification {
\brief Class that precomputes a 2D planimetric grid.
The grid is composed of squared cells with a user defined size,
The grid is composed of squared cells with a user-defined size,
each cell containing the list of indices of the points whose
projection along the Z-axis lies within this cell. The mapping
from each point to the its cell is also stored.
from each point to the cell it lies in is also stored.
\tparam Kernel model of \cgal Kernel.
\tparam Range range of items, model of `ConstRange`. Its iterator type
@ -85,21 +85,21 @@ public:
std::size_t height() const { return m_grid.height(); }
/*!
\brief Returns the indices of points lying in the given indexed cell.
\brief Returns the indices of the points lying in the cell at position `(x,y)`.
*/
const std::vector<std::size_t>& indices(std::size_t x, std::size_t y) const { return m_grid(x,y); }
/*!
\brief Returns `false` if the cell indexed by `(x,y)` is empty, `true` otherwise.
\brief Returns `false` if the cell at position `(x,y)` is empty, `true` otherwise.
*/
bool mask(std::size_t x, std::size_t y) const { return (!(m_grid(x,y).empty())); }
/*!
\brief Returns the `x` coordinate of the indexed point in the grid.
\brief Returns the `x` grid coordinate of the point at position `index`.
*/
std::size_t x(std::size_t index) const { return m_x[index]; }
/*!
\brief Returns the `y` coordinate of the indexed point in the grid.
\brief Returns the `y` grid coordinate of the point at position `index`.
*/
std::size_t y(std::size_t index) const { return m_y[index]; }
};

View File

@ -94,8 +94,8 @@ public:
public:
/*!
\brief Constructs a K neighbor query object.
\param neighborhood The point set neighborhood structure.
\param k The number of neighbors per query.
\param neighborhood point set neighborhood object.
\param k number of neighbors per query.
*/
K_neighbor_query (const Point_set_neighborhood& neighborhood, std::size_t k)
: neighborhood (neighborhood), k(k) { }
@ -126,8 +126,8 @@ public:
public:
/*!
\brief Constructs a range neighbor query object.
\param neighborhood The point set neighborhood structure.
\param radius The radius of the neighbor query.
\param neighborhood point set neighborhood object.
\param radius radius of the neighbor query sphere.
*/
Range_neighbor_query (const Point_set_neighborhood& neighborhood, double radius)
: neighborhood (neighborhood), radius(radius) { }
@ -242,7 +242,6 @@ private:
*(output ++) = it->first;
}
/// \cond SKIP_IN_MANUAL
template <typename Map>
void voxelize_point_set (std::vector<std::size_t>& indices, Map point_map,
double voxel_size)
@ -285,7 +284,6 @@ private:
indices.push_back (chosen);
}
}
/// \endcond
};

View File

@ -13,7 +13,7 @@ namespace Classification {
\ingroup PkgClassification
\brief %Classification type (for example: vegetation, ground, etc.)
defined as a set of relationship with classification attributes.
defined as a set of relationships with classification attributes.
*/
class Type
@ -29,18 +29,12 @@ private:
public:
/*!
\param name The name of the classification type
(e.g. vegetation).
\param name name of the classification type (e.g. vegetation).
*/
Type (std::string name) : m_name (name) { }
/*!
\brief Sets how an attribute affects the classification type.
\param att Attribute whose effect on the classification type is set
\param effect The effect the attribute has on the classification type
\brief Sets the effect of attribute `att` on the classification type.
*/
void set_attribute_effect (Attribute_handle att, Attribute::Effect effect)
{

View File

@ -58,7 +58,8 @@ namespace CGAL {
/*!
\ingroup PkgClassification
\brief Classifies a data set based on a set of attribute and a set of classification types.
\brief Classifies a data set based on a set of attributes and a set of
classification types.
This class implements the core of the classification algorithm
\cgalCite{cgal:lm-clscm-12}. It uses a data set as input and assignes
@ -67,26 +68,23 @@ defined classification types.
To achieve this classification algorithm, a set of local geometric
attributes are used, such as planarity, elevation or vertical
dispersion.
The user must define a set of classification types such as building,
ground or vegetation.
dispersion. In addition, the user must define a set of classification
types such as building, ground or vegetation.
Each pair of attribute and type must be assigned an
[Attribute::Effect](@ref CGAL::Classification::Attribute::Effect) (for
example, vegetation has a low planarity and a high vertical
dispersion) and each attribute must be assigned a weight. These
parameters can be set up by hand or by providing a training set for
each classification type.
parameters can be set up by hand or by automatic training, provided a
small user defined set of inlier is given for each classification
type.
\tparam Range range of items, model of `ConstRange`. Its iterator type
is `RandomAccessIterator`.
\tparam ItemMap model of `ReadablePropertyMap` whose key
type is the value type of the iterator of `Range` and value type is
`Point_3<Kernel>`.
the type of the items that are classified.
*/
template <typename Range,
typename ItemMap>
@ -133,18 +131,22 @@ public:
/*!
\brief Initializes a classification object.
\param input input range
\param item_map property map to access the input items
\param input input range.
\param item_map property map to access the input items.
*/
Classifier (const Range& input,
ItemMap item_map)
: m_input (input), m_item_map (item_map)
{
}
/// @}
/// \cond SKIP_IN_MANUAL
virtual ~Classifier() { }
/// \endcond
/// \name Classification
/// @{
@ -197,8 +199,8 @@ public:
local neighborhood of items. This method is a compromise between
efficiency and reliability.
\tparam NeighborQuery model of `NeighborQuery`
\param neighbor_query used to access neighborhoods of items
\tparam NeighborQuery model of `NeighborQuery`.
\param neighbor_query used to access neighborhoods of items.
*/
template <typename NeighborQuery>
void run_with_local_smoothing (const NeighborQuery& neighbor_query)
@ -260,8 +262,8 @@ public:
an alpha-expansion algorithm. This method is slow but provides
the user with good quality results.
\tparam NeighborQuery model of `NeighborQuery`
\param neighbor_query used to access neighborhoods of items
\tparam NeighborQuery model of `NeighborQuery`.
\param neighbor_query used to access neighborhoods of items.
\param weight weight of the regularization with respect to the
classification energy. Higher values produce more regularized
output but may result in a loss of details.
@ -323,7 +325,7 @@ public:
/// @{
/*!
\brief Instantiates and adds a classification type.
\brief Adds a classification type.
\param name name of the classification type.
@ -336,24 +338,13 @@ public:
return out;
}
/*!
\brief Adds a classification type.
\param type the handle to the classification type that must be added.
*/
void add_classification_type (Type_handle type)
{
m_types.push_back (type);
}
/*!
\brief Removes a classification type.
\param type the handle to the classification type that must be removed.
\return `true` if the classification type was correctly removed,
`false` if its handle was not found inside the object.
`false` if its handle was not found.
*/
bool remove_classification_type (Type_handle type)
{
@ -388,12 +379,15 @@ public:
return true;
}
/// \cond SKIP_IN_MANUAL
/*!
\brief Returns how many classification types are defined.
*/
std::size_t number_of_classification_types () const
{
return m_types.size();
}
/// \cond SKIP_IN_MANUAL
Type_handle get_classification_type (std::size_t idx)
{
return m_types[idx];
@ -419,7 +413,19 @@ public:
\param attribute %Handle of the attribute to add.
*/
#if !defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE)
/*!
\brief Adds an attribute.
\tparam Attribute type of the attribute, inherited from
`Classification::Attribute_base`.
\tparam T types of the parameters of the attribute's constructor.
\param t parameters of the attribute's constructor.
\return a handle to the newly added attribute.
*/
#if (!defined(CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES) && !defined(CGAL_CFG_NO_CPP0X_RVALUE_REFERENCE)) || DOXYGEN_RUNNING
template <typename Attribute, typename ... T>
Attribute_handle add_attribute (T&& ... t)
{
@ -465,6 +471,33 @@ public:
}
#endif
/*!
\brief Removes an attribute.
\param attribute the handle to attribute type that must be removed.
\return `true` if the attribute was correctly removed, `false` if
its handle was not found.
*/
bool remove_attribute (Attribute_handle attribute)
{
for (std::size_t i = 0; i < m_attributes.size(); ++ i)
if (m_attributes[i] == attribute)
{
m_attributes.erase (m_attributes.begin() + i);
return true;
}
return false;
}
/*!
\brief Returns how many attributes are defined.
*/
std::size_t number_of_attributes() const
{
return m_attributes.size();
}
/*!
\brief Removes all attributes.
*/
@ -473,12 +506,9 @@ public:
m_attributes.clear();
}
/// \cond SKIP_IN_MANUAL
std::size_t number_of_attributes() const
{
return m_attributes.size();
}
/// \cond SKIP_IN_MANUAL
Attribute_handle get_attribute(std::size_t idx)
{
return m_attributes[idx];
@ -491,15 +521,12 @@ public:
/// @{
/*!
\brief Gets the classification type of an indexed item.
\brief Returns the classification type of the item at position
`index`.
\note If classification was not performed (using `run()`,
`run_with_local_smoothing()` or `run_with_graphcut()`), this
function always returns the default `Type_handle`.
\param index index of the input item
\return handle to the classification type
*/
Type_handle classification_type_of (std::size_t index) const
{
@ -529,14 +556,16 @@ public:
/// \endcond
/*!
\brief Gets the confidence of the classification type of an indexed item.
\brief Returns the confidence of the classification type of the
item at position `index`.
\note If classification was not performed (using `run()`,
`run_with_local_smoothing()` or `run_with_graphcut()`), this
function always returns 0.
\param index index of the input item
\return confidence ranging from 0 (not confident at all) to 1 (very confident).
\return confidence ranging from 0 (not confident at all) to 1
(very confident).
*/
double confidence_of (std::size_t index) const
{
@ -555,8 +584,8 @@ public:
\brief Runs the training algorithm.
All the `Classification::Type` and `Classification::Attribute`
necessary for the classification should have been registered in
the object before running this function.
necessary for the classification should have been added before
running this function.
Each classification type must be given a small set of user-defined
inliers to provide the training algorithm with a ground truth.
@ -774,20 +803,24 @@ public:
/*!
\brief Resets training sets.
\brief Resets inlier sets used for training.
*/
void reset_training_sets()
void reset_inlier_sets()
{
std::vector<std::size_t>(m_input.size(), (std::size_t)(-1)).swap (m_training_type);
}
/*!
\brief Adds the input item specified by index `idx` as an inlier
of `class_type` for the training algorithm.
\brief Adds the item at position `idx` as an inlier of
`class_type` for the training algorithm.
\param class_type handle to the classification type.
\note This inlier is only used for training. There is no guarantee
that the item at position `idx` will be classified as `class_type`
after calling `run()`, `run_with_local_smoothing()` or
`run_with_graphcut()`.
\param idx index of the input item.
\return `true` if the inlier was correctly added, `false`
otherwise (if `class_type` was not found).
*/
bool set_inlier (Type_handle class_type, std::size_t idx)
{
@ -802,18 +835,21 @@ public:
return false;
if (m_training_type.empty())
reset_training_sets();
reset_inlier_sets();
m_training_type[idx] = type_idx;
return true;
}
/*!
\brief Adds input items specified by a range of indices as
inliers of `class_type` for the training algorithm.
\param class_type handle to the classification type.
\param indices Set of incides to add as inliers.
\brief Adds the items at positions `indices` as inliers of
`class_type` for the training algorithm.
\note These inliers are only used for training. There is no
guarantee that the items at positions `indices` will be classified
as `class_type` after calling `run()`,
`run_with_local_smoothing()` or `run_with_graphcut()`.
\tparam IndexRange range of `std::size_t`, model of `ConstRange`.
*/
@ -832,7 +868,7 @@ public:
return false;
if (m_training_type.empty())
reset_training_sets();
reset_inlier_sets();
for (typename IndexRange::const_iterator it = indices.begin();
it != indices.end(); ++ it)

View File

@ -50,7 +50,13 @@ namespace CGAL {
/*!
\ingroup PkgClassification
\brief TODO
\brief Classifies a point set based on a set of attributes and a set
of classification types.
This class specializes `Classifier` to point sets. It takes care of
generating necessary data structures and automatically generate a
set of generic attributes. Attributes can be generated at multiple
scales to increase the reliability of the classification.
\tparam Kernel model of \cgal Kernel.
\tparam Range range of items, model of `ConstRange`. Its iterator type
@ -183,19 +189,93 @@ private:
public:
/// \cond SKIP_IN_MANUAL
/// \name Constructor
/// @{
/*!
\brief Initializes a classification object.
\param input input range.
\param item_map property map to access the input points.
*/
Point_set_classifier(const Range& input, PointMap point_map) : Base (input, point_map)
{
m_bbox = CGAL::bounding_box
(boost::make_transform_iterator (m_input.begin(), CGAL::Property_map_to_unary_function<PointMap>(m_item_map)),
boost::make_transform_iterator (m_input.end(), CGAL::Property_map_to_unary_function<PointMap>(m_item_map)));
}
/// @}
/// \cond SKIP_IN_MANUAL
virtual ~Point_set_classifier()
{
clear();
}
/// \endcond
/// \name Attributes
/// @{
template <typename T>
const T& get_parameter (const T& t)
{
return t;
}
/*!
\brief Generate all possible attributes from an input range.
The smallest scale is automatically estimated and the data
structures needed (`Neighborhood`, `Planimetric_grid` and
`Local_eigen_analysis`) are computed at `nb_scales` recursively
larger scales. At each scale, the following attributes are
generated:
- `CGAL::Classification::Attribute::Anisotropy`
- `CGAL::Classification::Attribute::Distance_to_plane`
- `CGAL::Classification::Attribute::Eigentropy`
- `CGAL::Classification::Attribute::Elevation`
- `CGAL::Classification::Attribute::Linearity`
- `CGAL::Classification::Attribute::Omnivariance`
- `CGAL::Classification::Attribute::Planarity`
- `CGAL::Classification::Attribute::Sphericity`
- `CGAL::Classification::Attribute::Sum_eigenvalues`
- `CGAL::Classification::Attribute::Surface_variation`
- `CGAL::Classification::Attribute::Vertical_dispersion`
If normal vectors are provided (if `VectorMap` is different from
`CGAL::Default`), the following attribute is generated at each
scale:
- `CGAL::Classification::Attribute::Vertical_dispersion`
If colors are provided (if `ColorMap` is different from
`CGAL::Default`), the following attributes are generated at each
scale:
- 9 attributes `CGAL::Classification::Attribute::Hsv` on
channel 0 (hue) with mean ranging from 0° to 360° and standard
deviation of 22.5.
- 5 attributes `CGAL::Classification::Attribute::Hsv` on
channel 1 (saturation) with mean ranging from 0 to 100 and standard
deviation of 12.5.
- 5 attributes `CGAL::Classification::Attribute::Hsv` on channel 2
(value) with mean ranging from 0 to 100 and standard deviation
of 12.5.
If echo numbers are provided (if `EchoMap` is different from
`CGAL::Default`), the following attribute is computed at each
scale:
- `CGAL::Classification::Attribute::Echo_scatter`
\tparam VectorMap model of `ReadablePropertyMap` with value type `Vector_3<Kernel>`.
\tparam ColorMap model of `ReadablePropertyMap` with value type `CGAL::Classification::RGB_Color`.
\tparam EchoMap model of `ReadablePropertyMap` with value type `std::size_t`.
\param nb_scales number of scales to compute.
\param normal_map property map to access the normal vectors of the input points (if any).
\param color_map property map to access the colors of the input points (if any).
\param echo_map property map to access the echo values of the input points (if any).
*/
template <typename VectorMap = Default,
typename ColorMap = Default,
typename EchoMap = Default>
@ -217,83 +297,75 @@ public:
get_parameter<Emap>(echo_map));
}
/// @}
template <typename T>
Default_property_map<Iterator, T>
get_parameter (const Default&)
{
return Default_property_map<Iterator, T>();
}
template<typename VectorMap, typename ColorMap, typename EchoMap>
void generate_attributes_impl (std::size_t nb_scales,
VectorMap normal_map,
ColorMap color_map,
EchoMap echo_map)
{
m_bbox = CGAL::bounding_box
(boost::make_transform_iterator (m_input.begin(),
CGAL::Property_map_to_unary_function<PointMap>(m_item_map)),
boost::make_transform_iterator (m_input.end(),
CGAL::Property_map_to_unary_function<PointMap>(m_item_map)));
CGAL::Timer t; t.start();
m_scales.reserve (nb_scales);
double voxel_size = - 1.;
m_scales.push_back (new Scale (m_input, m_item_map, m_bbox, voxel_size));
voxel_size = m_scales[0]->grid_resolution();
for (std::size_t i = 1; i < nb_scales; ++ i)
{
voxel_size *= 2;
m_scales.push_back (new Scale (m_input, m_item_map, m_bbox, voxel_size));
}
generate_point_based_attributes ();
generate_normal_based_attributes (normal_map);
generate_color_based_attributes (color_map);
generate_echo_based_attributes (echo_map);
}
/// \cond SKIP_IN_MANUAL
virtual ~Point_set_classifier()
{
clear();
}
/// \endcond
/// \name Data Structures and Parameters
/// @{
/*!
\brief Returns the bounding box of the input point set.
*/
const Iso_cuboid_3& bbox() const { return m_bbox; }
/*!
\brief Returns the neighborhood structure at scale `scale`.
\note `generate_attributes()` must have been called before calling
this method.
*/
const Neighborhood& neighborhood(std::size_t scale = 0) const { return (*m_scales[scale]->neighborhood); }
/*!
\brief Returns the planimetric grid structure at scale `scale`.
\note `generate_attributes()` must have been called before calling
this method.
*/
const Planimetric_grid& grid(std::size_t scale = 0) const { return *(m_scales[scale]->grid); }
/*!
\brief Returns the local eigen analysis structure at scale `scale`.
\note `generate_attributes()` must have been called before calling
this method.
*/
const Local_eigen_analysis& eigen(std::size_t scale = 0) const { return *(m_scales[scale]->eigen); }
/*!
\brief Returns the grid resolution at scale `scale`.
\note `generate_attributes()` must have been called before calling
this method.
*/
double grid_resolution(std::size_t scale = 0) const { return m_scales[scale]->grid_resolution(); }
/*!
\brief Returns the radius used for neighborhood queries at scale `scale`.
\note `generate_attributes()` must have been called before calling
this method.
*/
double radius_neighbors(std::size_t scale = 0) const { return m_scales[scale]->radius_neighbors(); }
/*!
\brief Returns the radius used for digital terrain modeling at scale `scale`.
\note `generate_attributes()` must have been called before calling
this method.
*/
double radius_dtm(std::size_t scale = 0) const { return m_scales[scale]->radius_dtm(); }
/// @}
/*!
\brief Clears all computed data structures.
*/
void clear()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
delete m_scales[i];
m_scales.clear();
this->clear_classification_types();
this->clear_attributes();
}
/// @}
/// \cond SKIP_IN_MANUAL
void info() const
{
@ -314,69 +386,7 @@ public:
<< " (weight = " << m_scales[i]->attributes[j]->weight() << ")" << std::endl;
}
}
/// \endcond
/*!
\brief Clears all computed data structures.
*/
void clear()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
delete m_scales[i];
m_scales.clear();
this->clear_classification_types();
this->clear_attributes();
}
/*!
\brief Generate all possible attributes from an input range.
This method calls `generate_point_based_attributes()`,
`generate_normal_based_attributes()`,
`generate_color_based_attributes()` and
`generate_echo_based_attributes()`.
If a property map is left to its default
`CGAL::Default_property_map` type, the corresponding attributes are
not computed (this method can thus be called even if a point set
does not have associated normal, color or echo properties).
\tparam VectorMap is a model of `ReadablePropertyMap` with value type `Vector_3<Kernel>`.
\tparam ColorMap is a model of `ReadablePropertyMap` with value type `CGAL::Classification::RGB_Color`.
\tparam EchoMap is a model of `ReadablePropertyMap` with value type `std::size_`.
\param psc The classification object where to store the attributes
\param begin Iterator to the first input object
\param end Past-the-end iterator
\param point_map Property map to access the input points
\param normal_map Property map to access the normal vectors of the input points (if any).
\param color_map Property map to access the colors of the input points (if any).
\param echo_map Property map to access the echo values of the input points (if any).
*/
/*!
\brief Generate all points attributes from an input range.
Generate, for all precomputed scales, the following attributes:
- `CGAL::Classification::Attribute::Anisotropy`
- `CGAL::Classification::Attribute::Distance_to_plane`
- `CGAL::Classification::Attribute::Eigentropy`
- `CGAL::Classification::Attribute::Elevation`
- `CGAL::Classification::Attribute::Linearity`
- `CGAL::Classification::Attribute::Omnivariance`
- `CGAL::Classification::Attribute::Planarity`
- `CGAL::Classification::Attribute::Sphericity`
- `CGAL::Classification::Attribute::Sum_eigenvalues`
- `CGAL::Classification::Attribute::Surface_variation`
- `CGAL::Classification::Attribute::Vertical_dispersion`
\param psc The classification object where to store the attributes
\param begin Iterator to the first input object
\param end Past-the-end iterator
\param point_map Property map to access the input points
*/
void generate_point_based_attributes ()
{
CGAL::Timer teigen, tpoint;
@ -400,35 +410,9 @@ public:
std::cerr << "Eigen based attributes computed in " << teigen.time() << " second(s)" << std::endl;
}
/*!
\brief Generate all normal attributes from an input range.
Generate, for all precomputed scales, the following attribute:
- `CGAL::Classification::Attribute::Verticality`
If the normal map is left to its default type
`CGAL::Default_property_map`, then the verticality attributes are
still computed by using an approximation of the normal vector
provided by the corresponding `Local_eigen_analysis` object.
\tparam VectorMap Property map to access the normal vectors of the input points (if any).
\param psc The classification object where to store the attributes
\param begin Iterator to the first input object
\param end Past-the-end iterator
\param normal_map Property map to access the normal vectors of the input points (if any).
*/
#ifdef DOXYGEN_RUNNING
template<typename VectorMap = CGAL::Default_property_map<Iterator, typename Kernel::Vector_3> >
#else
template <typename VectorMap>
#endif
void generate_normal_based_attributes(
#ifdef DOXYGEN_RUNNING
VectorMap normal_map = VectorMap())
#else
VectorMap normal_map)
#endif
void generate_normal_based_attributes(VectorMap normal_map)
{
CGAL::Timer t; t.start();
this->template add_attribute<Verticality> (normal_map);
@ -437,42 +421,12 @@ public:
std::cerr << "Normal based attributes computed in " << t.time() << " second(s)" << std::endl;
}
/// \cond SKIP_IN_MANUAL
void generate_normal_based_attributes(const CGAL::Default_property_map<Iterator, typename Kernel::Vector_3>&
= CGAL::Default_property_map<Iterator, typename Kernel::Vector_3>())
void generate_normal_based_attributes(const CGAL::Default_property_map<Iterator, typename Kernel::Vector_3>&)
{
CGAL::Timer t; t.start();
generate_multiscale_attribute_variant_0<Verticality> ();
std::cerr << "Normal based attributes computed in " << t.time() << " second(s)" << std::endl;
}
/// \endcond
/*!
\brief Generate a set of color attributes from an input range.
Generate the following attributes:
- 9 attributes `CGAL::Classification::Attribute::Hsv` on
channel 0 (hue) with mean ranging from 0° to 360° and standard
deviation of 22.5.
- 5 attributes `CGAL::Classification::Attribute::Hsv` on
channel 1 (saturation) with mean ranging from 0 to 100 and standard
deviation of 12.5
- 5 attributes `CGAL::Classification::Attribute::Hsv` on
channel 2 (value) with mean ranging from 0 to 100 and standard
deviation of 12.5
This decomposition allows to handle all the color spectrum with a
usually sufficiently accurate precision.
\tparam ColorMap is a model of `ReadablePropertyMap` with value type `CGAL::Classification::RGB_Color`.
\param psc The classification object where to store the attributes
\param begin Iterator to the first input object
\param end Past-the-end iterator
\param color_map Property map to access the colors of the input points.
*/
template <typename ColorMap>
void generate_color_based_attributes(ColorMap color_map)
{
@ -498,25 +452,10 @@ public:
std::cerr << "Color based attributes computed in " << t.time() << " second(s)" << std::endl;
}
/// \cond SKIP_IN_MANUAL
void generate_color_based_attributes(const CGAL::Default_property_map<Iterator, RGB_Color>&)
{
}
/// \endcond
/*!
\brief Generate all echo attributes from an input range.
Generate, for all precomputed scales, the following attribute:
- `CGAL::Classification::Attribute::Echo_scatter`
\tparam EchoMap Property map to access the echo values of the input points (if any).
\param psc The classification object where to store the attributes
\param begin Iterator to the first input object
\param end Past-the-end iterator
\param echo_map Property map to access the echo values of the input points (if any).
*/
template <typename EchoMap>
void generate_echo_based_attributes(EchoMap echo_map)
{
@ -533,7 +472,6 @@ public:
std::cerr << "Echo based attributes computed in " << t.time() << " second(s)" << std::endl;
}
/// \cond SKIP_IN_MANUAL
void generate_echo_based_attributes(const CGAL::Default_property_map<Iterator, std::size_t>&)
{
}
@ -563,6 +501,8 @@ public:
}
/// \endcond
/// \name Input/Output
/// @{
/*!
\brief Saves the current configuration in the stream `output`.
@ -570,16 +510,12 @@ public:
This allows to easily save and recover a specific classification
configuration, that is to say:
- The smallest voxel size defined
- The computed scales
- The attributes and their respective weights
- The classification types and the effect the attributes have on them
The output file is written in an XML format that is readable by
the `load()` method and the constructor that takes a file name
as parameter.
\param output Output stream
\param psc Classification object whose attributes and types must be saved
the `load_configuration()` method.
*/
void save_configuration (std::ostream& output)
{
@ -636,26 +572,23 @@ public:
/*!
\brief Load a configuration from the stream `input`.
\brief Loads a configuration from the stream `input`.
All data structures, attributes and types specified in the input
stream `input` are instantiated if possible (in particular,
property maps needed should be provided).
property maps needed should be provided), similarly to what is
done in `generate_attributes()`.
The input file is written in an XML format written by the `save()`
method.
The input file should be in the XML format written by the
`save_configuration()` method.
\tparam VectorMap is a model of `ReadablePropertyMap` with value type `Vector_3<Kernel>`.
\tparam ColorMap is a model of `ReadablePropertyMap` with value type `CGAL::Classification::RGB_Color`.
\tparam EchoMap is a model of `ReadablePropertyMap` with value type `std::size_`.
\param input Input stream
\param psc Classification object where to store attributes and types
\param begin Iterator to the first input object
\param end Past-the-end iterator
\param point_map Property map to access the input points
\param normal_map Property map to access the normal vectors of the input points (if any).
\param color_map Property map to access the colors of the input points (if any).
\param echo_map Property map to access the echo values of the input points (if any).
\tparam VectorMap model of `ReadablePropertyMap` with value type `Vector_3<Kernel>`.
\tparam ColorMap model of `ReadablePropertyMap` with value type `CGAL::Classification::RGB_Color`.
\tparam EchoMap model of `ReadablePropertyMap` with value type `std::size_t`.
\param input input stream.
\param normal_map property map to access the normal vectors of the input points (if any).
\param color_map property map to access the colors of the input points (if any).
\param echo_map property map to access the echo values of the input points (if any).
*/
template<typename VectorMap = Default,
typename ColorMap = Default,
@ -678,6 +611,171 @@ public:
get_parameter<Emap>(echo_map));
}
/*!
\brief Writes a classification in a colored and labeled PLY format
in the stream `output`.
The input point set is written in a PLY format with the addition
of several PLY properties:
- a property `label` that indicates which classification type is
assigned to the point. The types are indexed from 0 to N (the
correspondancy is given as comments in the PLY header).
- 3 properties `red`, `green` and `blue` to associate each label
to a color (this is useful to visualize the classification in a
viewer that supports PLY colors). Colors are picked randomly.
\param stream The output stream where to write the content
\param begin Iterator to the first input object
\param end Past-the-end iterator
\param point_map Property map to access the input points
\param psc The classification object to write from
\param colors A set of colors to be used to represent the
different classification types. If none is given, random colors
are picked.
*/
void write_classification_to_ply (std::ostream& output)
{
output << "ply" << std::endl
<< "format ascii 1.0" << std::endl
<< "comment Generated by the CGAL library www.cgal.org" << std::endl
<< "element vertex " << m_input.size() << std::endl
<< "property double x" << std::endl
<< "property double y" << std::endl
<< "property double z" << std::endl
<< "property uchar red" << std::endl
<< "property uchar green" << std::endl
<< "property uchar blue" << std::endl
<< "property int label" << std::endl;
std::vector<RGB_Color> colors;
std::map<Type_handle, std::size_t> map_types;
output << "comment label -1 is (unclassified)" << std::endl;
for (std::size_t i = 0; i < this->number_of_classification_types(); ++ i)
{
map_types.insert (std::make_pair (this->get_classification_type(i), i));
output << "comment label " << i << " is " << this->get_classification_type(i)->name() << std::endl;
RGB_Color c = {{ (unsigned char)(64 + rand() % 128),
(unsigned char)(64 + rand() % 128),
(unsigned char)(64 + rand() % 128) }};
colors.push_back (c);
}
map_types.insert (std::make_pair (Type_handle(), this->number_of_classification_types()));
output << "end_header" << std::endl;
std::size_t i = 0;
for (Iterator it = m_input.begin(); it != m_input.end(); ++ it)
{
Type_handle t = this->classification_type_of(i);
std::size_t idx = map_types[t];
if (idx == this->number_of_classification_types())
output << get(m_item_map, *it) << " 0 0 0 -1" << std::endl;
else
output << get(m_item_map, *it) << " "
<< (int)(colors[idx][0]) << " "
<< (int)(colors[idx][1]) << " "
<< (int)(colors[idx][2]) << " "
<< idx << std::endl;
++ i;
}
}
/// @}
private:
template <typename T>
const T& get_parameter (const T& t)
{
return t;
}
template <typename T>
Default_property_map<Iterator, T>
get_parameter (const Default&)
{
return Default_property_map<Iterator, T>();
}
template<typename VectorMap, typename ColorMap, typename EchoMap>
void generate_attributes_impl (std::size_t nb_scales,
VectorMap normal_map,
ColorMap color_map,
EchoMap echo_map)
{
CGAL::Timer t; t.start();
m_scales.reserve (nb_scales);
double voxel_size = - 1.;
m_scales.push_back (new Scale (m_input, m_item_map, m_bbox, voxel_size));
voxel_size = m_scales[0]->grid_resolution();
for (std::size_t i = 1; i < nb_scales; ++ i)
{
voxel_size *= 2;
m_scales.push_back (new Scale (m_input, m_item_map, m_bbox, voxel_size));
}
generate_point_based_attributes ();
generate_normal_based_attributes (normal_map);
generate_color_based_attributes (color_map);
generate_echo_based_attributes (echo_map);
}
template <typename Attribute_type>
void generate_multiscale_attribute_variant_0 ()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
{
this->template add_attribute<Attribute_type>(*(m_scales[i]->eigen));
m_scales[i]->attributes.push_back (this->get_attribute (this->number_of_attributes() - 1));
}
}
template <typename Attribute_type>
void generate_multiscale_attribute_variant_1 ()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
{
this->template add_attribute<Attribute_type>(m_item_map, *(m_scales[i]->eigen));
m_scales[i]->attributes.push_back (this->get_attribute (this->number_of_attributes() - 1));
}
}
template <typename Attribute_type>
void generate_multiscale_attribute_variant_2 ()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
{
this->template add_attribute<Attribute_type>(m_item_map,
*(m_scales[i]->grid),
m_scales[i]->grid_resolution(),
m_scales[i]->radius_neighbors());
m_scales[i]->attributes.push_back (this->get_attribute (this->number_of_attributes() - 1));
}
}
template <typename Attribute_type>
void generate_multiscale_attribute_variant_3 ()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
{
this->template add_attribute<Attribute_type>(m_item_map,
*(m_scales[i]->grid),
m_scales[i]->grid_resolution(),
m_scales[i]->radius_dtm());
m_scales[i]->attributes.push_back (this->get_attribute (this->number_of_attributes() - 1));
}
}
template<typename VectorMap,typename ColorMap, typename EchoMap>
bool load_configuration_impl (std::istream& input,
VectorMap normal_map,
@ -689,10 +787,6 @@ public:
clear();
m_bbox = CGAL::bounding_box
(boost::make_transform_iterator (m_input.begin(), CGAL::Property_map_to_unary_function<PointMap>(m_item_map)),
boost::make_transform_iterator (m_input.end(), CGAL::Property_map_to_unary_function<PointMap>(m_item_map)));
boost::property_tree::ptree tree;
boost::property_tree::read_xml(input, tree);
@ -840,130 +934,6 @@ public:
return true;
}
/*!
\brief Writes a classification in a colored and labeled PLY format.
The input point set is written in a PLY format with the addition
of several PLY properties:
- a property `label` to indicate which classification type is
assigned to the point. The types are indexed from 0 to N (the
correspondancy is given as comments in the PLY header).
- 3 properties `red`, `green` and `blue` to associate each label
to a color (this is useful to visualize the classification in a
viewer that supports PLY colors)
\param stream The output stream where to write the content
\param begin Iterator to the first input object
\param end Past-the-end iterator
\param point_map Property map to access the input points
\param psc The classification object to write from
\param colors A set of colors to be used to represent the
different classification types. If none is given, random colors
are picked.
*/
void write_classification_to_ply (std::ostream& stream)
{
stream << "ply" << std::endl
<< "format ascii 1.0" << std::endl
<< "comment Generated by the CGAL library www.cgal.org" << std::endl
<< "element vertex " << m_input.size() << std::endl
<< "property double x" << std::endl
<< "property double y" << std::endl
<< "property double z" << std::endl
<< "property uchar red" << std::endl
<< "property uchar green" << std::endl
<< "property uchar blue" << std::endl
<< "property int label" << std::endl;
std::vector<RGB_Color> colors;
std::map<Type_handle, std::size_t> map_types;
stream << "comment label -1 is (unclassified)" << std::endl;
for (std::size_t i = 0; i < this->number_of_classification_types(); ++ i)
{
map_types.insert (std::make_pair (this->get_classification_type(i), i));
stream << "comment label " << i << " is " << this->get_classification_type(i)->name() << std::endl;
RGB_Color c = {{ (unsigned char)(64 + rand() % 128),
(unsigned char)(64 + rand() % 128),
(unsigned char)(64 + rand() % 128) }};
colors.push_back (c);
}
map_types.insert (std::make_pair (Type_handle(), this->number_of_classification_types()));
stream << "end_header" << std::endl;
std::size_t i = 0;
for (Iterator it = m_input.begin(); it != m_input.end(); ++ it)
{
Type_handle t = this->classification_type_of(i);
std::size_t idx = map_types[t];
if (idx == this->number_of_classification_types())
stream << get(m_item_map, *it) << " 0 0 0 -1" << std::endl;
else
stream << get(m_item_map, *it) << " "
<< (int)(colors[idx][0]) << " "
<< (int)(colors[idx][1]) << " "
<< (int)(colors[idx][2]) << " "
<< idx << std::endl;
++ i;
}
}
private:
/// \cond SKIP_IN_MANUAL
template <typename Attribute_type>
void generate_multiscale_attribute_variant_0 ()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
{
this->template add_attribute<Attribute_type>(*(m_scales[i]->eigen));
m_scales[i]->attributes.push_back (this->get_attribute (this->number_of_attributes() - 1));
}
}
template <typename Attribute_type>
void generate_multiscale_attribute_variant_1 ()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
{
this->template add_attribute<Attribute_type>(m_item_map, *(m_scales[i]->eigen));
m_scales[i]->attributes.push_back (this->get_attribute (this->number_of_attributes() - 1));
}
}
template <typename Attribute_type>
void generate_multiscale_attribute_variant_2 ()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
{
this->template add_attribute<Attribute_type>(m_item_map,
*(m_scales[i]->grid),
m_scales[i]->grid_resolution(),
m_scales[i]->radius_neighbors());
m_scales[i]->attributes.push_back (this->get_attribute (this->number_of_attributes() - 1));
}
}
template <typename Attribute_type>
void generate_multiscale_attribute_variant_3 ()
{
for (std::size_t i = 0; i < m_scales.size(); ++ i)
{
this->template add_attribute<Attribute_type>(m_item_map,
*(m_scales[i]->grid),
m_scales[i]->grid_resolution(),
m_scales[i]->radius_dtm());
m_scales[i]->attributes.push_back (this->get_attribute (this->number_of_attributes() - 1));
}
}
/// \endcond
};
} // namespace CGAL

View File

@ -143,7 +143,7 @@ class SCENE_POINT_SET_CLASSIFICATION_ITEM_EXPORT Scene_point_set_classification_
void reset_training_sets()
{
m_psc->prepare_classification();
m_psc->reset_training_sets();
m_psc->reset_inlier_sets();
invalidateOpenGLBuffers();
Q_EMIT itemChanged();
}