Merge pull request #3625 from sgiraudot/Stream_support-Enhance_color-GF
[Small Feature] Reworked CGAL::Color
This commit is contained in:
@@ -1,140 +0,0 @@
|
||||
// Copyright (c) 2017 GeometryFactory Sarl (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
// Author(s) : Simon Giraudot
|
||||
|
||||
#ifndef CGAL_CLASSIFICATION_COLOR_H
|
||||
#define CGAL_CLASSIFICATION_COLOR_H
|
||||
|
||||
#include <CGAL/license/Classification.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/int.h>
|
||||
#include <CGAL/array.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Classification {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationColor
|
||||
|
||||
%Color described in red/green/blue space. Each component is stored
|
||||
as an unsigned char ranging from 0 (no color) to 255 (full color).
|
||||
*/
|
||||
typedef std::array<unsigned char, 3> RGB_Color;
|
||||
/*!
|
||||
\ingroup PkgClassificationColor
|
||||
|
||||
%Color described in hue/saturation/value space. Each component is stored
|
||||
as a float:
|
||||
|
||||
- `hue` ranges from 0° to 360° (corresponding to the color tint)
|
||||
- `saturation` ranges from 0.0 (gray) to 100.0 (full saturation)
|
||||
- `value` ranges from 0.0 (black) to 100.0 (white)
|
||||
*/
|
||||
typedef std::array<float, 3> HSV_Color;
|
||||
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
inline HSV_Color rgb_to_hsv (const RGB_Color& c)
|
||||
{
|
||||
double r = (double)(c[0]) / 255.;
|
||||
double g = (double)(c[1]) / 255.;
|
||||
double b = (double)(c[2]) / 255.;
|
||||
double Cmax = (std::max) (r, (std::max) (g, b));
|
||||
double Cmin = (std::min) (r, (std::min) (g, b));
|
||||
double delta = Cmax - Cmin;
|
||||
double H = 0.;
|
||||
|
||||
if (delta != 0.)
|
||||
{
|
||||
if (Cmax == r)
|
||||
H = 60. * ((g - b) / delta);
|
||||
else if (Cmax == g)
|
||||
H = 60. * (((b - r) / delta) + 2.);
|
||||
else
|
||||
H = 60. * (((r - g) / delta) + 4.);
|
||||
}
|
||||
if (H < 0.) H += 360.;
|
||||
double S = (Cmax == 0. ? 0. : 100. * (delta / Cmax));
|
||||
double V = 100. * Cmax;
|
||||
HSV_Color out = {{ float(H), float(S), float(V) }};
|
||||
return out;
|
||||
}
|
||||
|
||||
inline RGB_Color hsv_to_rgb (const HSV_Color& c)
|
||||
{
|
||||
double h = c[0];
|
||||
double s = c[1];
|
||||
double v = c[2];
|
||||
|
||||
s /= 100.;
|
||||
v /= 100.;
|
||||
double C = v*s;
|
||||
int hh = (int)(h/60.);
|
||||
double X = C * (1-CGAL::abs (hh % 2 - 1));
|
||||
double r = 0, g = 0, b = 0;
|
||||
|
||||
if( hh>=0 && hh<1 )
|
||||
{
|
||||
r = C;
|
||||
g = X;
|
||||
}
|
||||
else if( hh>=1 && hh<2 )
|
||||
{
|
||||
r = X;
|
||||
g = C;
|
||||
}
|
||||
else if( hh>=2 && hh<3 )
|
||||
{
|
||||
g = C;
|
||||
b = X;
|
||||
}
|
||||
else if( hh>=3 && hh<4 )
|
||||
{
|
||||
g = X;
|
||||
b = C;
|
||||
}
|
||||
else if( hh>=4 && hh<5 )
|
||||
{
|
||||
r = X;
|
||||
b = C;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = C;
|
||||
b = X;
|
||||
}
|
||||
double m = v-C;
|
||||
r += m;
|
||||
g += m;
|
||||
b += m;
|
||||
r *= 255.0;
|
||||
g *= 255.0;
|
||||
b *= 255.0;
|
||||
|
||||
RGB_Color out = {{ (unsigned char)r, (unsigned char)g, (unsigned char)b }};
|
||||
return out;
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
} // namespace Classification
|
||||
} // namespace CGAL
|
||||
|
||||
|
||||
|
||||
#endif // CGAL_CLASSIFICATION_COLOR_H
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <CGAL/Classification/Color.h>
|
||||
#include <CGAL/Classification/Feature_base.h>
|
||||
#include <CGAL/array.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace Feature {
|
||||
`ColorMap`.
|
||||
\tparam ColorMap model of `ReadablePropertyMap` whose key
|
||||
type is the value type of the iterator of `PointRange` and value type
|
||||
is `CGAL::Classification::RGB_Color`.
|
||||
is `CGAL::Color`.
|
||||
*/
|
||||
template <typename GeomTraits, typename PointRange, typename ColorMap>
|
||||
class Color_channel : public Feature_base
|
||||
@@ -82,9 +82,6 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Classification::RGB_Color RGB_Color;
|
||||
typedef typename Classification::HSV_Color HSV_Color;
|
||||
|
||||
const PointRange& input;
|
||||
ColorMap color_map;
|
||||
Channel m_channel;
|
||||
@@ -111,8 +108,8 @@ public:
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
virtual float value (std::size_t pt_index)
|
||||
{
|
||||
HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+pt_index)));
|
||||
return c[std::size_t(m_channel)];
|
||||
cpp11::array<double, 3> c = get(color_map, *(input.begin()+pt_index)).to_hsv();
|
||||
return float(c[std::size_t(m_channel)]);
|
||||
}
|
||||
/// \endcond
|
||||
};
|
||||
|
||||
@@ -1,431 +0,0 @@
|
||||
// Copyright (c) 2017 GeometryFactory Sarl (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
// Author(s) : Simon Giraudot
|
||||
|
||||
#ifndef CGAL_CLASSIFICATION_FEATURES_EIGEN_H
|
||||
#define CGAL_CLASSIFICATION_FEATURES_EIGEN_H
|
||||
|
||||
#include <CGAL/license/Classification.h>
|
||||
|
||||
#include <vector>
|
||||
#include <CGAL/Classification/Feature_base.h>
|
||||
#include <CGAL/Classification/Local_eigen_analysis.h>
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace Classification {
|
||||
|
||||
namespace Feature {
|
||||
|
||||
class Eigen_feature : public Feature_base
|
||||
{
|
||||
protected:
|
||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
||||
std::vector<float> attrib;
|
||||
#else
|
||||
const Classification::Local_eigen_analysis& eigen;
|
||||
#endif
|
||||
|
||||
public:
|
||||
template <typename InputRange>
|
||||
Eigen_feature (const InputRange&,
|
||||
const Classification::Local_eigen_analysis& eigen)
|
||||
#ifndef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
||||
: eigen (eigen)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
||||
virtual void init (std::size_t size, const Classification::Local_eigen_analysis& eigen)
|
||||
{
|
||||
attrib.reserve (size);
|
||||
for (std::size_t i = 0; i < size; ++ i)
|
||||
attrib.push_back (get_value (eigen, i));
|
||||
}
|
||||
#else
|
||||
virtual void init (std::size_t, const Classification::Local_eigen_analysis&)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual float get_value (const Classification::Local_eigen_analysis& eigen, std::size_t i) = 0;
|
||||
virtual float value (std::size_t pt_index)
|
||||
{
|
||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
||||
return attrib[pt_index];
|
||||
#else
|
||||
return get_value(eigen, pt_index);
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationFeatures
|
||||
|
||||
%Feature based on the eigenvalues of the covariance matrix of a
|
||||
local neighborhood. Linearity is defined, for the 3 eigenvalues
|
||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
||||
|
||||
\f[
|
||||
\frac{\lambda_1 - \lambda_2}{\lambda_1}
|
||||
\f]
|
||||
|
||||
Its default name is "linearity".
|
||||
*/
|
||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Linearity, please update your code with Eigenvalue instead")
|
||||
class Linearity
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
: public Feature_base
|
||||
#else
|
||||
: public Eigen_feature
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Constructs the feature.
|
||||
|
||||
\tparam Input model of `ConstRange`. Its iterator type
|
||||
is `RandomAccessIterator`.
|
||||
\param input point range.
|
||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
||||
*/
|
||||
template <typename InputRange>
|
||||
Linearity (const InputRange& input,
|
||||
const Local_eigen_analysis& eigen) : Eigen_feature (input, eigen)
|
||||
{
|
||||
this->set_name("linearity");
|
||||
this->init(input.size(), eigen);
|
||||
}
|
||||
|
||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
||||
{
|
||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
||||
if (ev[2] < 1e-15)
|
||||
return 0.;
|
||||
else
|
||||
return ((ev[2] - ev[1]) / ev[2]);
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationFeatures
|
||||
|
||||
%Feature based on the eigenvalues of the covariance matrix of a
|
||||
local neighborhood. Planarity is defined, for the 3 eigenvalues
|
||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
||||
|
||||
\f[
|
||||
\frac{\lambda_2 - \lambda_3}{\lambda_1}
|
||||
\f]
|
||||
|
||||
Its default name is "planarity".
|
||||
*/
|
||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Planarity, please update your code with Eigenvalue instead")
|
||||
class Planarity
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
: public Feature_base
|
||||
#else
|
||||
: public Eigen_feature
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Constructs the feature.
|
||||
|
||||
\param input point range.
|
||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
||||
*/
|
||||
template <typename InputRange>
|
||||
Planarity (const InputRange& input,
|
||||
const Local_eigen_analysis& eigen)
|
||||
: Eigen_feature(input, eigen)
|
||||
{
|
||||
this->set_name("planarity");
|
||||
this->init(input.size(), eigen);
|
||||
}
|
||||
|
||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
||||
{
|
||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
||||
if (ev[2] < 1e-15)
|
||||
return 0.;
|
||||
else
|
||||
return ((ev[1] - ev[0]) / ev[2]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationFeatures
|
||||
|
||||
%Feature based on the eigenvalues of the covariance matrix of a
|
||||
local neighborhood. Sphericity is defined, for the 3 eigenvalues
|
||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
||||
|
||||
\f[
|
||||
\frac{\lambda_3}{\lambda_1}
|
||||
\f]
|
||||
|
||||
Its default name is "sphericity".
|
||||
*/
|
||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Sphericity, please update your code with Eigenvalue instead")
|
||||
class Sphericity
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
: public Feature_base
|
||||
#else
|
||||
: public Eigen_feature
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Constructs the feature.
|
||||
|
||||
\param input point range.
|
||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
||||
*/
|
||||
template <typename InputRange>
|
||||
Sphericity (const InputRange& input,
|
||||
const Local_eigen_analysis& eigen)
|
||||
: Eigen_feature(input, eigen)
|
||||
{
|
||||
this->set_name("sphericity");
|
||||
this->init(input.size(), eigen);
|
||||
}
|
||||
|
||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
||||
{
|
||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
||||
if (ev[2] < 1e-15)
|
||||
return 0.;
|
||||
else
|
||||
return (ev[0] / ev[2]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationFeatures
|
||||
|
||||
%Feature based on the eigenvalues of the covariance matrix of a
|
||||
local neighborhood. Omnivariance is defined, for the 3 eigenvalues
|
||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
||||
|
||||
\f[
|
||||
(\lambda_1 \times \lambda_2 \times \lambda_3)^{\frac{1}{3}}
|
||||
\f]
|
||||
|
||||
Its default name is "omnivariance".
|
||||
*/
|
||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Omnivariance, please update your code with Eigenvalue instead")
|
||||
class Omnivariance
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
: public Feature_base
|
||||
#else
|
||||
: public Eigen_feature
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Constructs the feature.
|
||||
|
||||
\param input point range.
|
||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
||||
*/
|
||||
template <typename InputRange>
|
||||
Omnivariance (const InputRange& input,
|
||||
const Local_eigen_analysis& eigen)
|
||||
: Eigen_feature(input, eigen)
|
||||
{
|
||||
this->set_name("omnivariance");
|
||||
this->init(input.size(), eigen);
|
||||
}
|
||||
|
||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
||||
{
|
||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
||||
return (std::pow (CGAL::abs(ev[0] * ev[1] * ev[2]), 0.333333333f));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationFeatures
|
||||
|
||||
%Feature based on the eigenvalues of the covariance matrix of a
|
||||
local neighborhood. Anisotropy is defined, for the 3 eigenvalues
|
||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
||||
|
||||
\f[
|
||||
\frac{\lambda_1 - \lambda_3}{\lambda_1}
|
||||
\f]
|
||||
|
||||
Its default name is "anisotropy".
|
||||
*/
|
||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Anisotropy, please update your code with Eigenvalue instead")
|
||||
class Anisotropy
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
: public Feature_base
|
||||
#else
|
||||
: public Eigen_feature
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Constructs the feature.
|
||||
|
||||
\param input point range.
|
||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
||||
*/
|
||||
template <typename InputRange>
|
||||
Anisotropy (const InputRange& input,
|
||||
const Local_eigen_analysis& eigen)
|
||||
: Eigen_feature(input, eigen)
|
||||
{
|
||||
this->set_name("anisotropy");
|
||||
this->init(input.size(), eigen);
|
||||
}
|
||||
|
||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
||||
{
|
||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
||||
if (ev[2] < 1e-15)
|
||||
return 0.;
|
||||
else
|
||||
return ((ev[2] - ev[0]) / ev[2]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationFeatures
|
||||
|
||||
%Feature based on the eigenvalues of the covariance matrix of a
|
||||
local neighborhood. Eigentropy is defined, for the 3 eigenvalues
|
||||
\f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge 0\f$, as:
|
||||
|
||||
\f[
|
||||
- \sum_{i=1}^3 \lambda_i \times \log{\lambda_i}
|
||||
\f]
|
||||
|
||||
Its default name is "eigentropy".
|
||||
*/
|
||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Eigentropy, please update your code with Eigenvalue instead")
|
||||
class Eigentropy
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
: public Feature_base
|
||||
#else
|
||||
: public Eigen_feature
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Constructs the feature.
|
||||
|
||||
\param input point range.
|
||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
||||
*/
|
||||
template <typename InputRange>
|
||||
Eigentropy (const InputRange& input,
|
||||
const Local_eigen_analysis& eigen)
|
||||
: Eigen_feature(input, eigen)
|
||||
{
|
||||
this->set_name("eigentropy");
|
||||
this->init(input.size(), eigen);
|
||||
}
|
||||
|
||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
||||
{
|
||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
||||
if (ev[0] < 1e-15
|
||||
|| ev[1] < 1e-15
|
||||
|| ev[2] < 1e-15)
|
||||
return 0.;
|
||||
else
|
||||
return (- ev[0] * std::log(ev[0])
|
||||
- ev[1] * std::log(ev[1])
|
||||
- ev[2] * std::log(ev[2]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationFeatures
|
||||
|
||||
%Feature based on the eigenvalues of the covariance
|
||||
matrix of a local neighborhood. Surface variation is defined, for
|
||||
the 3 eigenvalues \f$\lambda_1 \ge \lambda_2 \ge \lambda_3 \ge
|
||||
0\f$, as:
|
||||
|
||||
\f[
|
||||
\frac{\lambda_3}{\lambda_1 + \lambda_2 + \lambda_3}
|
||||
\f]
|
||||
|
||||
Its default name is "surface_variation".
|
||||
*/
|
||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Surface_variation, please update your code with Eigenvalue instead")
|
||||
class Surface_variation
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
: public Feature_base
|
||||
#else
|
||||
: public Eigen_feature
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
Constructs the feature.
|
||||
|
||||
\param input point range.
|
||||
\param eigen class with precomputed eigenvectors and eigenvalues.
|
||||
*/
|
||||
template <typename InputRange>
|
||||
Surface_variation (const InputRange& input,
|
||||
const Local_eigen_analysis& eigen)
|
||||
: Eigen_feature(input, eigen)
|
||||
{
|
||||
this->set_name("surface_variation");
|
||||
this->init(input.size(), eigen);
|
||||
}
|
||||
|
||||
virtual float get_value (const Local_eigen_analysis& eigen, std::size_t i)
|
||||
{
|
||||
const Local_eigen_analysis::Eigenvalues& ev = eigen.eigenvalue(i);
|
||||
if (ev[0] + ev[1] + ev[2] < 1e-15)
|
||||
return 0.;
|
||||
else
|
||||
return (ev[0] / (ev[0] + ev[1] + ev[2]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace Feature
|
||||
|
||||
} // namespace Classification
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif
|
||||
/// \endcond
|
||||
|
||||
#endif // CGAL_CLASSIFICATION_FEATURES_EIGEN_H
|
||||
@@ -1,175 +0,0 @@
|
||||
// Copyright (c) 2017 GeometryFactory Sarl (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
// Author(s) : Simon Giraudot
|
||||
|
||||
#ifndef CGAL_CLASSIFICATION_FEATURE_HSV_H
|
||||
#define CGAL_CLASSIFICATION_FEATURE_HSV_H
|
||||
|
||||
#include <CGAL/license/Classification.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <CGAL/Classification/Color.h>
|
||||
#include <CGAL/Classification/Feature_base.h>
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace Classification {
|
||||
|
||||
namespace Feature {
|
||||
|
||||
/*!
|
||||
\ingroup PkgClassificationFeatures
|
||||
|
||||
%Feature based on HSV colorimetric information. If the input
|
||||
point cloud has colorimetric information, it can be used for
|
||||
classification purposes. This feature is based on a Gaussian
|
||||
probabilistic model on one of the three HSV channels (hue,
|
||||
saturation or value). It computes the probability of the color of
|
||||
the input point to match this specific color channel defined by a
|
||||
mean and a standard deviation.
|
||||
|
||||
The HSV channels are defined this way:
|
||||
|
||||
- Hue ranges from 0 to 360 and measures the general "tint" of the
|
||||
color (green, blue, pink, etc.)
|
||||
|
||||
- Saturation ranges from 0 to 100 and measures the "strength" of the
|
||||
color (0 is gray and 100 is the fully saturated color)
|
||||
|
||||
- Value ranges from 0 to 100 and measures the "brightness" of the
|
||||
color (0 is black and 100 is the fully bright color)
|
||||
|
||||
For example, such an feature using the channel 0 (hue) with a
|
||||
mean of 90 (which corresponds to a green hue) can help to identify
|
||||
trees.
|
||||
|
||||
\image html trees.png
|
||||
|
||||
<center><em>Left: input point set with colors. Right: HSV feature on hue with
|
||||
a mean of 90 (from low values in white to high values in dark
|
||||
red).</em></center>
|
||||
|
||||
Its default name is the channel followed by the mean value (for
|
||||
example: "hue_180", "saturation_20" or "value_98").
|
||||
|
||||
\note The user only needs to provide a map to standard (and more common)
|
||||
RGB colors, the conversion to HSV is done internally.
|
||||
|
||||
\tparam GeomTraits model of \cgal Kernel.
|
||||
\tparam PointRange model of `ConstRange`. Its iterator type
|
||||
is `RandomAccessIterator` and its value type is the key type of
|
||||
`ColorMap`.
|
||||
\tparam ColorMap model of `ReadablePropertyMap` whose key
|
||||
type is the value type of the iterator of `PointRange` and value type
|
||||
is `CGAL::Classification::RGB_Color`.
|
||||
*/
|
||||
template <typename GeomTraits, typename PointRange, typename ColorMap>
|
||||
CGAL_DEPRECATED_MSG("you are using the deprecated feature Hsv, please update your code with Color_channel instead")
|
||||
class Hsv : public Feature_base
|
||||
{
|
||||
public:
|
||||
|
||||
/// Selected channel.
|
||||
enum Channel
|
||||
{
|
||||
HUE = 0, ///< 0
|
||||
SATURATION = 1, ///< 1
|
||||
VALUE = 2 ///< 2
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
typedef typename Classification::RGB_Color RGB_Color;
|
||||
typedef typename Classification::HSV_Color HSV_Color;
|
||||
|
||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
||||
std::vector<float> color_feature;
|
||||
#else
|
||||
const PointRange& input;
|
||||
ColorMap color_map;
|
||||
Channel m_channel;
|
||||
float m_mean;
|
||||
float m_sd;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
/*!
|
||||
|
||||
\brief Constructs a feature based on the given color channel,
|
||||
mean and standard deviation.
|
||||
|
||||
\param input point range.
|
||||
\param color_map property map to access the colors of the input points.
|
||||
\param channel chosen HSV channel.
|
||||
\param mean mean value of the specified channel.
|
||||
\param sd standard deviation of the specified channel.
|
||||
*/
|
||||
Hsv (const PointRange& input,
|
||||
ColorMap color_map,
|
||||
Channel channel,
|
||||
float mean, float sd)
|
||||
#ifndef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
||||
: input(input), color_map(color_map), m_channel(channel), m_mean(mean), m_sd(sd)
|
||||
#endif
|
||||
{
|
||||
|
||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
||||
for(std::size_t i = 0; i < input.size();i++)
|
||||
{
|
||||
HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+i)));
|
||||
color_feature.push_back (std::exp (-(c[std::size_t(channel)] - mean)
|
||||
* (c[std::size_t(channel)] - mean) / (2. * sd * sd)));
|
||||
}
|
||||
#endif
|
||||
std::ostringstream oss;
|
||||
if (channel == HUE) oss << "hue";
|
||||
else if (channel == SATURATION) oss << "saturation";
|
||||
else if (channel == VALUE) oss << "value";
|
||||
oss << "_" << mean;
|
||||
this->set_name (oss.str());
|
||||
}
|
||||
|
||||
virtual float value (std::size_t pt_index)
|
||||
{
|
||||
#ifdef CGAL_CLASSIFICATION_PRECOMPUTE_FEATURES
|
||||
return color_feature[pt_index];
|
||||
#else
|
||||
HSV_Color c = Classification::rgb_to_hsv (get(color_map, *(input.begin()+pt_index)));
|
||||
return std::exp (-(c[std::size_t(m_channel)] - m_mean)
|
||||
* (c[std::size_t(m_channel)] - m_mean) / (2.f * m_sd * m_sd));
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace Feature
|
||||
|
||||
} // namespace Classification
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif
|
||||
/// \endcond
|
||||
|
||||
#endif // CGAL_CLASSIFICATION_FEATURE_HSV_H
|
||||
@@ -152,8 +152,6 @@ public:
|
||||
typedef Classification::Feature::Verticality
|
||||
<GeomTraits> Verticality;
|
||||
typedef Classification::Feature::Eigenvalue Eigenvalue;
|
||||
|
||||
typedef typename Classification::RGB_Color RGB_Color;
|
||||
/// \endcond
|
||||
|
||||
private:
|
||||
|
||||
@@ -153,8 +153,6 @@ public:
|
||||
typedef Classification::Feature::Gradient_of_feature
|
||||
<PointRange, PointMap, Neighbor_query> Gradient_of_feature;
|
||||
#endif
|
||||
|
||||
typedef typename Classification::RGB_Color RGB_Color;
|
||||
/// \endcond
|
||||
|
||||
private:
|
||||
@@ -294,64 +292,6 @@ public:
|
||||
/// @}
|
||||
|
||||
/// \cond SKIP_IN_MANUAL
|
||||
|
||||
#ifndef CGAL_NO_DEPRECATED_CODE
|
||||
// deprecated
|
||||
template <typename VectorMap = Default,
|
||||
typename ColorMap = Default,
|
||||
typename EchoMap = Default>
|
||||
CGAL_DEPRECATED_MSG("you are using a deprecated constructor of CGAL::Classification::Point_set_feature_generator, please update your code")
|
||||
Point_set_feature_generator(Feature_set& features,
|
||||
const PointRange& input,
|
||||
PointMap point_map,
|
||||
std::size_t nb_scales,
|
||||
VectorMap normal_map = VectorMap(),
|
||||
ColorMap color_map = ColorMap(),
|
||||
EchoMap echo_map = EchoMap(),
|
||||
float voxel_size = -1.f)
|
||||
: m_input (input), m_point_map (point_map)
|
||||
{
|
||||
m_bbox = CGAL::bounding_box
|
||||
(boost::make_transform_iterator (m_input.begin(), CGAL::Property_map_to_unary_function<PointMap>(m_point_map)),
|
||||
boost::make_transform_iterator (m_input.end(), CGAL::Property_map_to_unary_function<PointMap>(m_point_map)));
|
||||
|
||||
CGAL::Real_timer t; t.start();
|
||||
|
||||
m_scales.reserve (nb_scales);
|
||||
|
||||
m_scales.push_back (new Scale (m_input, m_point_map, m_bbox, voxel_size));
|
||||
|
||||
if (voxel_size == -1.f)
|
||||
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_point_map, m_bbox, voxel_size, m_scales[i-1]->grid));
|
||||
}
|
||||
t.stop();
|
||||
CGAL_CLASSIFICATION_CERR << "Scales computed in " << t.time() << " second(s)" << std::endl;
|
||||
t.reset();
|
||||
|
||||
typedef typename Default::Get<VectorMap, typename GeomTraits::Vector_3 >::type
|
||||
Vmap;
|
||||
typedef typename Default::Get<ColorMap, RGB_Color >::type
|
||||
Cmap;
|
||||
typedef typename Default::Get<EchoMap, std::size_t >::type
|
||||
Emap;
|
||||
|
||||
generate_point_based_features (features);
|
||||
generate_normal_based_features (features, get_parameter<Vmap>(normal_map));
|
||||
generate_color_based_features (features, get_parameter<Cmap>(color_map));
|
||||
generate_echo_based_features (features, get_parameter<Emap>(echo_map));
|
||||
}
|
||||
|
||||
// Functions to remove when deprecated constructor is removed
|
||||
void generate_normal_based_features(const CGAL::Constant_property_map<Iterator, typename GeomTraits::Vector_3>&) { }
|
||||
void generate_color_based_features(const CGAL::Constant_property_map<Iterator, RGB_Color>&) { }
|
||||
void generate_echo_based_features(const CGAL::Constant_property_map<Iterator, std::size_t>&) { }
|
||||
#endif
|
||||
|
||||
virtual ~Point_set_feature_generator()
|
||||
{
|
||||
clear();
|
||||
@@ -434,7 +374,7 @@ public:
|
||||
|
||||
\tparam ColorMap model of `ReadablePropertyMap` whose key type is
|
||||
the value type of the iterator of `PointRange` and value type is
|
||||
`CGAL::Classification::RGB_Color`.
|
||||
`CGAL::Color`.
|
||||
|
||||
\param features the feature set where the features are instantiated.
|
||||
\param color_map property map to access the colors of the input points (if any).
|
||||
|
||||
Reference in New Issue
Block a user