Use signed integer for label indices (better handling of unlabeled -1 case)

This commit is contained in:
Simon Giraudot 2017-08-09 09:57:15 +02:00
parent 8043d342e7
commit 2ebc55e9c3
8 changed files with 163 additions and 227 deletions

View File

@ -3,19 +3,20 @@
#include <iostream>
#include <string>
//#define CGAL_CLASSIFICATION_VERBOSE
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Classification.h>
#include <CGAL/IO/read_ply_points.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/Real_timer.h>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Point_set_3<Point> Point_set;
typedef Kernel::Iso_cuboid_3 Iso_cuboid_3;
typedef std::vector<Point> Point_range;
typedef CGAL::Identity_property_map<Point> Pmap;
typedef typename Point_set::Point_map Pmap;
typedef typename Point_set::Property_map<int> Imap;
namespace Classification = CGAL::Classification;
@ -24,68 +25,34 @@ typedef Classification::Feature_handle
typedef Classification::Label_set Label_set;
typedef Classification::Feature_set Feature_set;
typedef Classification::Sum_of_weighted_features_classifier Classifier;
typedef Classification::Sum_of_weighted_features_classifier Classifier;
typedef Classification::Point_set_feature_generator<Kernel, Point_range, Pmap> Feature_generator;
/*
This interpreter is used to read a PLY input that contains training
attributes (with the PLY "label" property).
*/
class My_ply_interpreter
{
std::vector<Point>& points;
std::vector<std::size_t>& labels;
public:
My_ply_interpreter (std::vector<Point>& points,
std::vector<std::size_t>& labels)
: points (points), labels (labels)
{ }
// Init and test if input file contains the right properties
bool is_applicable (CGAL::Ply_reader& reader)
{
return reader.does_tag_exist<double> ("x")
&& reader.does_tag_exist<double> ("y")
&& reader.does_tag_exist<double> ("z")
&& reader.does_tag_exist<int> ("label");
}
// Describes how to process one line (= one point object)
void process_line (CGAL::Ply_reader& reader)
{
double x = 0., y = 0., z = 0.;
int l = 0;
reader.assign (x, "x");
reader.assign (y, "y");
reader.assign (z, "z");
reader.assign (l, "label");
points.push_back (Point (x, y, z));
labels.push_back(std::size_t(l));
}
};
typedef Classification::Point_set_feature_generator<Kernel, Point_set, Pmap> Feature_generator;
int main (int argc, char** argv)
{
std::string filename (argc > 1 ? argv[1] : "data/b9_training.ply");
std::ifstream in (filename.c_str());
std::vector<Point> pts;
std::vector<std::size_t> ground_truth;
Point_set pts;
std::cerr << "Reading input" << std::endl;
My_ply_interpreter interpreter (pts, ground_truth);
if (!in
|| !(CGAL::read_ply_custom_points (in, interpreter, Kernel())))
in >> pts;
Imap label_map;
bool lm_found = false;
boost::tie (label_map, lm_found) = pts.property_map<int> ("label");
if (!lm_found)
{
std::cerr << "Error: cannot read " << filename << std::endl;
std::cerr << "Error: \"label\" property not found in input file." << std::endl;
return EXIT_FAILURE;
}
std::vector<int> ground_truth;
ground_truth.reserve (pts.size());
std::copy (pts.range(label_map).begin(), pts.range(label_map).end(),
std::back_inserter (ground_truth));
///////////////////////////////////////////////////////////////////
//! [Generator]
@ -94,7 +61,7 @@ int main (int argc, char** argv)
std::cerr << "Generating features" << std::endl;
CGAL::Real_timer t;
t.start();
Feature_generator generator (features, pts, Pmap(),
Feature_generator generator (features, pts, pts.point_map(),
5); // using 5 scales
t.stop();
std::cerr << features.size() << " feature(s) generated in " << t.time() << " second(s)" << std::endl;
@ -107,7 +74,6 @@ int main (int argc, char** argv)
Label_handle ground = labels.add ("ground");
Label_handle vegetation = labels.add ("vegetation");
Label_handle roof = labels.add ("roof");
Label_handle facade = labels.add ("facade");
Classifier classifier (labels, features);
@ -120,9 +86,9 @@ int main (int argc, char** argv)
t.reset();
t.start();
std::vector<std::size_t> label_indices;
std::vector<int> label_indices(pts.size(), -1);
Classification::classify_with_graphcut<CGAL::Sequential_tag>
(pts, Pmap(), labels, classifier,
(pts, pts.point_map(), labels, classifier,
generator.neighborhood().k_neighbor_query(12),
0.2, 10, label_indices);
t.stop();

View File

@ -3,20 +3,22 @@
#include <iostream>
#include <string>
//#define CGAL_CLASSIFICATION_VERBOSE
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Classification.h>
#include <CGAL/Classification/Random_forest_classifier.h>
#include <CGAL/IO/read_ply_points.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/Real_timer.h>
typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Point_set_3<Point> Point_set;
typedef Kernel::Iso_cuboid_3 Iso_cuboid_3;
typedef std::vector<Point> Point_range;
typedef CGAL::Identity_property_map<Point> Pmap;
typedef typename Point_set::Point_map Pmap;
typedef typename Point_set::Property_map<int> Imap;
typedef typename Point_set::Property_map<unsigned char> UCmap;
namespace Classification = CGAL::Classification;
@ -27,72 +29,38 @@ typedef Classification::Feature_set
typedef Classification::Random_forest_classifier Classifier;
typedef Classification::Point_set_feature_generator<Kernel, Point_range, Pmap> Feature_generator;
/*
This interpreter is used to read a PLY input that contains training
attributes (with the PLY "label" property).
*/
class My_ply_interpreter
{
std::vector<Point>& points;
std::vector<std::size_t>& labels;
public:
My_ply_interpreter (std::vector<Point>& points,
std::vector<std::size_t>& labels)
: points (points), labels (labels)
{ }
// Init and test if input file contains the right properties
bool is_applicable (CGAL::Ply_reader& reader)
{
return reader.does_tag_exist<double> ("x")
&& reader.does_tag_exist<double> ("y")
&& reader.does_tag_exist<double> ("z")
&& reader.does_tag_exist<int> ("label");
}
// Describes how to process one line (= one point object)
void process_line (CGAL::Ply_reader& reader)
{
double x = 0., y = 0., z = 0.;
int l = 0;
reader.assign (x, "x");
reader.assign (y, "y");
reader.assign (z, "z");
reader.assign (l, "label");
points.push_back (Point (x, y, z));
labels.push_back(std::size_t(l));
}
};
typedef Classification::Point_set_feature_generator<Kernel, Point_set, Pmap> Feature_generator;
int main (int argc, char** argv)
{
std::string filename (argc > 1 ? argv[1] : "data/b9_training.ply");
std::ifstream in (filename.c_str());
std::vector<Point> pts;
std::vector<std::size_t> ground_truth;
Point_set pts;
std::cerr << "Reading input" << std::endl;
My_ply_interpreter interpreter (pts, ground_truth);
if (!in
|| !(CGAL::read_ply_custom_points (in, interpreter, Kernel())))
in >> pts;
Imap label_map;
bool lm_found = false;
boost::tie (label_map, lm_found) = pts.property_map<int> ("label");
if (!lm_found)
{
std::cerr << "Error: cannot read " << filename << std::endl;
std::cerr << "Error: \"label\" property not found in input file." << std::endl;
return EXIT_FAILURE;
}
std::vector<int> ground_truth;
ground_truth.reserve (pts.size());
std::copy (pts.range(label_map).begin(), pts.range(label_map).end(),
std::back_inserter (ground_truth));
Feature_set features;
std::cerr << "Generating features" << std::endl;
CGAL::Real_timer t;
t.start();
Feature_generator generator (features, pts, Pmap(),
Feature_generator generator (features, pts, pts.point_map(),
5); // using 5 scales
t.stop();
std::cerr << "Done in " << t.time() << " second(s)" << std::endl;
@ -102,7 +70,6 @@ int main (int argc, char** argv)
Label_handle ground = labels.add ("ground");
Label_handle vegetation = labels.add ("vegetation");
Label_handle roof = labels.add ("roof");
Label_handle facade = labels.add ("facade");
Classifier classifier (labels, features);
@ -115,11 +82,11 @@ int main (int argc, char** argv)
t.reset();
t.start();
std::vector<std::size_t> label_indices;
std::vector<int> label_indices(pts.size(), -1);
Classification::classify_with_graphcut<CGAL::Sequential_tag>
(pts, Pmap(), labels, classifier,
(pts, pts.point_map(), labels, classifier,
generator.neighborhood().k_neighbor_query(12),
0.2, 10, label_indices);
0.2, 1, label_indices);
t.stop();
std::cerr << "Classification with graphcut done in " << t.time() << " second(s)" << std::endl;
@ -138,40 +105,37 @@ int main (int argc, char** argv)
std::cerr << "Accuracy = " << evaluation.accuracy() << std::endl
<< "Mean F1 score = " << evaluation.mean_f1_score() << std::endl
<< "Mean IoU = " << evaluation.mean_intersection_over_union() << std::endl;
std::ofstream f ("classification.ply");
f.precision(18);
f << "ply" << std::endl
<< "format ascii 1.0" << std::endl
<< "element vertex " << pts.size() << std::endl
<< "property float x" << std::endl
<< "property float y" << std::endl
<< "property float z" << std::endl
<< "property uchar red" << std::endl
<< "property uchar green" << std::endl
<< "property uchar blue" << std::endl
<< "end_header" << std::endl;
for (std::size_t i = 0; i < pts.size(); ++ i)
// Color point set according to class
UCmap red = pts.add_property_map<unsigned char>("red", 0).first;
UCmap green = pts.add_property_map<unsigned char>("green", 0).first;
UCmap blue = pts.add_property_map<unsigned char>("blue", 0).first;
for (std::size_t i = 0; i < label_indices.size(); ++ i)
{
f << pts[i] << " ";
label_map[i] = label_indices[i]; // update label map with computed classification
Label_handle label = labels[label_indices[i]];
if (label == ground)
f << "245 180 0" << std::endl;
else if (label == vegetation)
f << "0 255 27" << std::endl;
else if (label == roof)
f << "255 0 170" << std::endl;
else if (label == facade)
f << "128 128 128" << std::endl;
else
{
f << "0 0 0" << std::endl;
std::cerr << "Error: unknown classification label" << std::endl;
red[i] = 245; green[i] = 180; blue[i] = 0;
}
else if (label == vegetation)
{
red[i] = 0; green[i] = 255; blue[i] = 27;
}
else if (label == roof)
{
red[i] = 255; green[i] = 0; blue[i] = 170;
}
}
// Write result
std::ofstream f ("classification.ply");
f.precision(18);
f << pts;
std::cerr << "All done" << std::endl;
return EXIT_SUCCESS;

View File

@ -18,7 +18,7 @@
// Author(s) : Simon Giraudot
#ifndef CGAL_CLASSIFICATION_EVALUATION_H
#define CGAL_CLASSIFICATION_EVALUATION_H_
#define CGAL_CLASSIFICATION_EVALUATION_H
#include <CGAL/Classification/Label.h>
#include <CGAL/Classification/Label_set.h>
@ -60,15 +60,16 @@ public:
\param ground_truth vector of label indices: it should contain the
index of the corresponding label in the `Label_set` provided in the
constructor. Input items that do not have a ground truth information
should be given the value `std::size_t(-1)`.
should be given the value `-1`.
\param result similar to `ground_truth` but contained the result of
a classification.
*/
template <typename LabelIndexRange>
Evaluation (const Label_set& labels,
const std::vector<std::size_t>& ground_truth,
const std::vector<std::size_t>& result)
const LabelIndexRange& ground_truth,
const LabelIndexRange& result)
: m_precision (labels.size()),
m_recall (labels.size()),
m_iou (labels.size())
@ -85,9 +86,9 @@ public:
for (std::size_t j = 0; j < ground_truth.size(); ++ j)
{
std::size_t gt = ground_truth[j];
std::size_t res = result[j];
if (gt == std::size_t(-1) || res == std::size_t(-1))
int gt = static_cast<int>(ground_truth[j]);
int res = static_cast<int>(result[j]);
if (gt == -1 || res == -1)
continue;
++ total;
if (gt == res)
@ -217,4 +218,5 @@ public:
} // namespace CGAL
#endif // CGAL_CLASSIFICATION_EVALUATION_H_
#endif // CGAL_CLASSIFICATION_EVALUATION_H

View File

@ -91,9 +91,10 @@ public:
each input item, in the same order as the input set, the index of
the corresponding label in the `Label_set` provided in the
constructor. Input items that do not have a ground truth
information should be given the value `std::size_t(-1)`.
information should be given the value `-1`.
*/
void train (const std::vector<std::size_t>& ground_truth)
template <typename LabelIndexRange>
void train (const LabelIndexRange& ground_truth)
{
#if (CV_MAJOR_VERSION < 3)
if (rtree != NULL)
@ -102,15 +103,14 @@ public:
std::size_t nb_samples = 0;
for (std::size_t i = 0; i < ground_truth.size(); ++ i)
if (ground_truth[i] != std::size_t(-1))
if (ground_truth[i] != -1)
++ nb_samples;
cv::Mat training_features (nb_samples, m_features.size(), CV_32FC1);
cv::Mat training_labels (nb_samples, 1, CV_32FC1);
for (std::size_t i = 0, index = 0; i < ground_truth.size(); ++ i)
if (ground_truth[i] != std::size_t(-1))
if (ground_truth[i] != -1)
{
for (std::size_t f = 0; f < m_features.size(); ++ f)
training_features.at<float>(index, f) = m_features[f]->value(i);

View File

@ -284,7 +284,7 @@ public:
each input item, in the same order as the input set, the index of
the corresponding label in the `Label_set` provided in the
constructor. Input items that do not have a ground truth
information should be given the value `std::size_t(-1)`.
information should be given the value `-1`.
\param nb_tests number of tests to perform. Higher values may
provide the user with better results at the cost of a higher
@ -295,16 +295,16 @@ public:
provided ground truth and the best classification found by the
training set.
*/
template <typename ConcurrencyTag>
float train (const std::vector<std::size_t>& ground_truth,
template <typename ConcurrencyTag, typename LabelIndexRange>
float train (const LabelIndexRange& ground_truth,
unsigned int nb_tests = 300)
{
std::vector<std::vector<std::size_t> > training_sets (m_labels.size());
std::size_t nb_tot = 0;
for (std::size_t i = 0; i < ground_truth.size(); ++ i)
if (ground_truth[i] != std::size_t(-1))
if (ground_truth[i] != -1)
{
training_sets[ground_truth[i]].push_back (i);
training_sets[std::size_t(ground_truth[i])].push_back (i);
++ nb_tot;
}
@ -486,16 +486,16 @@ public:
/// @}
/// \cond SKIP_IN_MANUAL
template <typename ConcurrencyTag>
float train_random (const std::vector<std::size_t>& ground_truth,
template <typename ConcurrencyTag, typename LabelIndexRange>
float train_random (const LabelIndexRange& ground_truth,
unsigned int nb_tests = 300)
{
std::vector<std::vector<std::size_t> > training_sets (m_labels.size());
std::size_t nb_tot = 0;
for (std::size_t i = 0; i < ground_truth.size(); ++ i)
if (ground_truth[i] != std::size_t(-1))
if (ground_truth[i] != -1)
{
training_sets[ground_truth[i]].push_back (i);
training_sets[std::size_t(ground_truth[i])].push_back (i);
++ nb_tot;
}

View File

@ -40,18 +40,18 @@ namespace Classification {
/// \cond SKIP_IN_MANUAL
namespace internal {
template <typename Classifier>
template <typename Classifier, typename LabelIndexRange>
class Classify_functor
{
const Label_set& m_labels;
const Classifier& m_classifier;
std::vector<std::size_t>& m_out;
LabelIndexRange& m_out;
public:
Classify_functor (const Label_set& labels,
const Classifier& classifier,
std::vector<std::size_t>& out)
LabelIndexRange& out)
: m_labels (labels), m_classifier (classifier), m_out (out)
{ }
@ -79,7 +79,7 @@ namespace internal {
}
}
m_out[s] = nb_class_best;
m_out[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
}
};
@ -117,7 +117,7 @@ namespace internal {
}
};
template <typename ItemRange, typename ItemMap, typename NeighborQuery>
template <typename ItemRange, typename ItemMap, typename NeighborQuery, typename LabelIndexRange>
class Classify_functor_local_smoothing
{
const ItemRange& m_input;
@ -125,7 +125,7 @@ namespace internal {
const Label_set& m_labels;
const std::vector<std::vector<float> >& m_values;
const NeighborQuery& m_neighbor_query;
std::vector<std::size_t>& m_out;
LabelIndexRange& m_out;
public:
@ -134,7 +134,7 @@ namespace internal {
const Label_set& labels,
const std::vector<std::vector<float> >& values,
const NeighborQuery& neighbor_query,
std::vector<std::size_t>& out)
LabelIndexRange& out)
: m_input (input), m_item_map (item_map), m_labels (labels),
m_values(values),
m_neighbor_query (neighbor_query),
@ -171,14 +171,15 @@ namespace internal {
}
}
m_out[s] = nb_class_best;
m_out[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
}
};
template <typename ItemRange, typename ItemMap,
typename Classifier, typename NeighborQuery>
typename Classifier, typename NeighborQuery,
typename LabelIndexRange>
class Classify_functor_graphcut
{
const ItemRange& m_input;
@ -189,7 +190,7 @@ namespace internal {
float m_strength;
const std::vector<std::vector<std::size_t> >& m_indices;
const std::vector<std::pair<std::size_t, std::size_t> >& m_input_to_indices;
std::vector<std::size_t>& m_out;
LabelIndexRange& m_out;
#ifdef CGAL_DO_NOT_USE_BOYKOV_KOLMOGOROV_MAXFLOW_SOFTWARE
typedef CGAL::internal::Alpha_expansion_graph_cut_boost Alpha_expansion;
@ -207,7 +208,7 @@ namespace internal {
float strength,
const std::vector<std::vector<std::size_t> >& indices,
const std::vector<std::pair<std::size_t, std::size_t> >& input_to_indices,
std::vector<std::size_t>& out)
LabelIndexRange& out)
: m_input (input), m_item_map (item_map), m_labels (labels),
m_classifier (classifier), m_neighbor_query (neighbor_query),
m_strength (strength), m_indices (indices), m_input_to_indices (input_to_indices), m_out (out)
@ -271,7 +272,7 @@ namespace internal {
graphcut(edges, edge_weights, probability_matrix, assigned_label);
for (std::size_t i = 0; i < assigned_label.size(); ++ i)
m_out[m_indices[sub][i]] = assigned_label[i];
m_out[m_indices[sub][i]] = static_cast<typename LabelIndexRange::iterator::value_type>(assigned_label[i]);
}
};
@ -299,6 +300,9 @@ namespace internal {
\tparam Classifier model of `Classifier`.
\tparam Model of `Range` with random access iterators whose value
type is an integer type.
\param input input range.
\param labels set of input labels.
\param classifier input classifier.
@ -309,15 +313,16 @@ namespace internal {
*/
template <typename ConcurrencyTag,
typename ItemRange,
typename Classifier>
typename Classifier,
typename LabelIndexRange>
void classify (const ItemRange& input,
const Label_set& labels,
const Classifier& classifier,
std::vector<std::size_t>& output)
LabelIndexRange& output)
{
output.resize(input.size());
internal::Classify_functor<Classifier>
internal::Classify_functor<Classifier, LabelIndexRange>
f (labels, classifier, output);
#ifndef CGAL_LINKED_WITH_TBB
@ -354,6 +359,8 @@ namespace internal {
is the type of item to classify (for example, `CGAL::Point_3`).
\tparam NeighborQuery model of `NeighborQuery`.
\tparam Classifier model of `Classifier`.
\tparam Model of `Range` with random access iterators whose value
type is an integer type.
\param input input range.
\param item_map property map to access the input items.
@ -369,13 +376,14 @@ namespace internal {
typename ItemRange,
typename ItemMap,
typename NeighborQuery,
typename Classifier>
typename Classifier,
typename LabelIndexRange>
void classify_with_local_smoothing (const ItemRange& input,
const ItemMap item_map,
const Label_set& labels,
const Classifier& classifier,
const NeighborQuery& neighbor_query,
std::vector<std::size_t>& output)
LabelIndexRange& output)
{
output.resize(input.size());
@ -383,7 +391,7 @@ namespace internal {
(labels.size(), std::vector<float> (input.size(), -1.));
internal::Classify_functor_local_smoothing_preprocessing<Classifier>
f1 (labels, classifier, values);
internal::Classify_functor_local_smoothing<ItemRange, ItemMap, NeighborQuery>
internal::Classify_functor_local_smoothing<ItemRange, ItemMap, NeighborQuery, LabelIndexRange>
f2 (input, item_map, labels, values, neighbor_query, output);
#ifndef CGAL_LINKED_WITH_TBB
@ -431,6 +439,8 @@ namespace internal {
is the type of item to classify (for example, `CGAL::Point_3`).
\tparam NeighborQuery model of `NeighborQuery`.
\tparam Classifier model of `Classifier`.
\tparam Model of `Range` with random access iterators whose value
type is an integer type.
\param input input range.
\param item_map property map to access the input items.
@ -452,7 +462,8 @@ namespace internal {
typename ItemRange,
typename ItemMap,
typename NeighborQuery,
typename Classifier>
typename Classifier,
typename LabelIndexRange>
void classify_with_graphcut (const ItemRange& input,
const ItemMap item_map,
const Label_set& labels,
@ -460,7 +471,7 @@ namespace internal {
const NeighborQuery& neighbor_query,
const float strength,
const std::size_t min_number_of_subdivisions,
std::vector<std::size_t>& output)
LabelIndexRange& output)
{
CGAL::Bbox_3 bbox = CGAL::bbox_3
(boost::make_transform_iterator (input.begin(), CGAL::Property_map_to_unary_function<ItemMap>(item_map)),
@ -510,9 +521,7 @@ namespace internal {
}
}
output.resize (input.size());
internal::Classify_functor_graphcut<ItemRange, ItemMap, Classifier, NeighborQuery>
internal::Classify_functor_graphcut<ItemRange, ItemMap, Classifier, NeighborQuery, LabelIndexRange>
f (input, item_map, labels, classifier, neighbor_query, strength, indices, input_to_indices, output);
#ifndef CGAL_LINKED_WITH_TBB

View File

@ -24,51 +24,45 @@ Point_set_item_classification::Point_set_item_classification(Scene_points_with_n
reset_indices();
backup_existing_colors_and_add_new();
m_training = m_points->point_set()->add_property_map<std::size_t>("training", std::size_t(-1)).first;
m_classif = m_points->point_set()->add_property_map<std::size_t>("label", std::size_t(-1)).first;
bool training_found = false;
boost::tie (m_training, training_found) = m_points->point_set()->add_property_map<int>("training", -1);
bool classif_found = false;
boost::tie (m_classif, classif_found) = m_points->point_set()->add_property_map<int>("label", -1);
Point_set::Property_map<int> ps_labels;
bool found;
boost::tie (ps_labels, found) = m_points->point_set()->property_map<int>("label");
Point_set::Property_map<signed char> ps_labels_c;
bool found_c;
boost::tie (ps_labels_c, found_c) = m_points->point_set()->property_map<signed char>("label");
if (found || found_c)
training_found = !training_found; // add_property_map returns false if
classif_found = !classif_found; // property was already there
if (training_found || classif_found)
{
int max = 0;
int lmax = 0;
for (Point_set::const_iterator it = m_points->point_set()->begin();
it != m_points->point_set()->first_selected(); ++ it)
{
int l;
if (found) l = ps_labels[*it];
else l = int(ps_labels_c[*it] - 1);
m_classif[*it] = (std::size_t)l;
m_training[*it] = (std::size_t)l;
if (l > max)
if (training_found)
{
max = l;
int l = m_training[*it];
lmax = (std::max)(l, lmax);
}
if (classif_found)
{
int l = m_classif[*it];
lmax = (std::max)(l, lmax);
}
}
for (int i = 0; i < max; ++ i)
for (int i = 0; i <= lmax; ++ i)
{
std::ostringstream oss;
oss << "label_" << i;
m_labels.add(oss.str().c_str());
CGAL::Classification::HSV_Color hsv;
hsv[0] = 360. * (i / double(max));
hsv[0] = 360. * (i / double(lmax));
hsv[1] = 76.;
hsv[2] = 85.;
Color rgb = CGAL::Classification::hsv_to_rgb(hsv);
m_label_colors.push_back (QColor(rgb[0], rgb[1], rgb[2]));
}
if (found)
m_points->point_set()->remove_property_map(ps_labels);
else
m_points->point_set()->remove_property_map(ps_labels_c);
}
else
{
@ -235,11 +229,11 @@ void Point_set_item_classification::change_color (int index)
it != m_points->point_set()->first_selected(); ++ it)
{
QColor color (0, 0, 0);
std::size_t c = m_training[*it];
std::size_t c2 = m_classif[*it];
int c = m_training[*it];
int c2 = m_classif[*it];
if (c != std::size_t(-1))
color = m_label_colors[c];
if (c != -1)
color = m_label_colors[std::size_t(c)];
float div = 1;
if (c != c2)
@ -363,15 +357,16 @@ void Point_set_item_classification::train(int classifier)
}
reset_indices();
std::vector<int> training (m_points->point_set()->size(), -1);
std::vector<std::size_t> indices (m_points->point_set()->size(), std::size_t(-1));
for (Point_set::const_iterator it = m_points->point_set()->begin();
it != m_points->point_set()->first_selected(); ++ it)
indices[*it] = m_training[*it];
training[*it] = m_training[*it];
if (classifier == 0)
{
m_sowf->train<Concurrency_tag>(indices, m_nb_trials);
m_sowf->train<Concurrency_tag>(training, m_nb_trials);
CGAL::Classification::classify<Concurrency_tag> (*(m_points->point_set()),
m_labels, *m_sowf,
indices);
@ -379,7 +374,7 @@ void Point_set_item_classification::train(int classifier)
else
{
#ifdef CGAL_LINKED_WITH_OPENCV
m_random_forest->train (indices);
m_random_forest->train (training);
CGAL::Classification::classify<Concurrency_tag> (*(m_points->point_set()),
m_labels, *m_random_forest,
indices);
@ -387,7 +382,7 @@ void Point_set_item_classification::train(int classifier)
}
for (Point_set::const_iterator it = m_points->point_set()->begin();
it != m_points->point_set()->first_selected(); ++ it)
m_classif[*it] = indices[*it];
m_classif[*it] = int(indices[*it]);
if (m_index_color == 1 || m_index_color == 2)
change_color (m_index_color);

View File

@ -49,7 +49,7 @@ class Point_set_item_classification : public Item_classification_base
void add_selection_to_training_set (const char* name)
{
std::size_t label = get_label (name);
int label = int(get_label (name));
for (Point_set::const_iterator it = m_points->point_set()->first_selected();
it != m_points->point_set()->end(); ++ it)
@ -66,7 +66,7 @@ class Point_set_item_classification : public Item_classification_base
{
for (Point_set::const_iterator it = m_points->point_set()->begin();
it != m_points->point_set()->end(); ++ it)
m_training[*it] = std::size_t(-1);
m_training[*it] = -1;
}
void validate_selection ()
{
@ -116,7 +116,7 @@ class Point_set_item_classification : public Item_classification_base
template <typename Classifier>
bool run (int method, const Classifier& classifier)
{
std::vector<std::size_t> indices;
std::vector<int> indices (m_points->point_set()->size(), std::size_t(-1));
if (method == 0)
CGAL::Classification::classify<Concurrency_tag> (*(m_points->point_set()),
@ -134,7 +134,7 @@ class Point_set_item_classification : public Item_classification_base
m_generator->neighborhood().k_neighbor_query(12),
m_smoothing, m_subdivisions, indices);
std::vector<std::size_t> ground_truth(m_points->point_set()->size(), std::size_t(-1));
std::vector<int> ground_truth(m_points->point_set()->size(), -1);
for (Point_set::const_iterator it = m_points->point_set()->begin();
it != m_points->point_set()->first_selected(); ++ it)
{
@ -172,8 +172,8 @@ class Point_set_item_classification : public Item_classification_base
Point_set::Property_map<unsigned char> m_green;
Point_set::Property_map<unsigned char> m_blue;
Point_set::Property_map<Color> m_color;
Point_set::Property_map<std::size_t> m_training;
Point_set::Property_map<std::size_t> m_classif;
Point_set::Property_map<int> m_training;
Point_set::Property_map<int> m_classif;
Generator* m_generator;