mirror of https://github.com/CGAL/cgal
Use CGAL::for_each in classify functions
This commit is contained in:
parent
7b4c664403
commit
d9b5f4f1e5
|
|
@ -17,9 +17,12 @@
|
||||||
|
|
||||||
#include <CGAL/internal/Surface_mesh_segmentation/Alpha_expansion_graph_cut.h>
|
#include <CGAL/internal/Surface_mesh_segmentation/Alpha_expansion_graph_cut.h>
|
||||||
#include <CGAL/Bbox_3.h>
|
#include <CGAL/Bbox_3.h>
|
||||||
|
#include <CGAL/for_each.h>
|
||||||
#include <CGAL/Classification/Label_set.h>
|
#include <CGAL/Classification/Label_set.h>
|
||||||
#include <CGAL/property_map.h>
|
#include <CGAL/property_map.h>
|
||||||
|
|
||||||
|
#include <boost/iterator/counting_iterator.hpp>
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
#ifdef CGAL_LINKED_WITH_TBB
|
||||||
#include <tbb/parallel_for.h>
|
#include <tbb/parallel_for.h>
|
||||||
#include <tbb/blocked_range.h>
|
#include <tbb/blocked_range.h>
|
||||||
|
|
@ -31,299 +34,6 @@ namespace CGAL {
|
||||||
|
|
||||||
namespace Classification {
|
namespace Classification {
|
||||||
|
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
template <typename Classifier, typename LabelIndexRange>
|
|
||||||
class Classify_functor
|
|
||||||
{
|
|
||||||
const Label_set& m_labels;
|
|
||||||
const Classifier& m_classifier;
|
|
||||||
LabelIndexRange& m_out;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Classify_functor (const Label_set& labels,
|
|
||||||
const Classifier& classifier,
|
|
||||||
LabelIndexRange& out)
|
|
||||||
: m_labels (labels), m_classifier (classifier), m_out (out)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
|
||||||
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
|
||||||
{
|
|
||||||
for (std::size_t s = r.begin(); s != r.end(); ++ s)
|
|
||||||
apply(s);
|
|
||||||
}
|
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
|
||||||
|
|
||||||
inline void apply (std::size_t s) const
|
|
||||||
{
|
|
||||||
std::size_t nb_class_best=0;
|
|
||||||
std::vector<float> values;
|
|
||||||
m_classifier (s, values);
|
|
||||||
|
|
||||||
float val_class_best = 0.f;
|
|
||||||
for(std::size_t k = 0; k < m_labels.size(); ++ k)
|
|
||||||
{
|
|
||||||
if(val_class_best < values[k])
|
|
||||||
{
|
|
||||||
val_class_best = values[k];
|
|
||||||
nb_class_best = k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_out[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Classifier, typename LabelIndexRange, typename ProbabilitiesRanges>
|
|
||||||
class Classify_detailed_output_functor
|
|
||||||
{
|
|
||||||
const Label_set& m_labels;
|
|
||||||
const Classifier& m_classifier;
|
|
||||||
LabelIndexRange& m_out;
|
|
||||||
ProbabilitiesRanges& m_prob;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Classify_detailed_output_functor (const Label_set& labels,
|
|
||||||
const Classifier& classifier,
|
|
||||||
LabelIndexRange& out,
|
|
||||||
ProbabilitiesRanges& prob)
|
|
||||||
: m_labels (labels), m_classifier (classifier), m_out (out), m_prob (prob)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
|
||||||
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
|
||||||
{
|
|
||||||
for (std::size_t s = r.begin(); s != r.end(); ++ s)
|
|
||||||
apply(s);
|
|
||||||
}
|
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
|
||||||
|
|
||||||
inline void apply (std::size_t s) const
|
|
||||||
{
|
|
||||||
std::size_t nb_class_best=0;
|
|
||||||
std::vector<float> values;
|
|
||||||
m_classifier (s, values);
|
|
||||||
|
|
||||||
float val_class_best = 0.f;
|
|
||||||
for(std::size_t k = 0; k < m_labels.size(); ++ k)
|
|
||||||
{
|
|
||||||
m_prob[k][s] = values[k];
|
|
||||||
if(val_class_best < values[k])
|
|
||||||
{
|
|
||||||
val_class_best = values[k];
|
|
||||||
nb_class_best = k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_out[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Classifier>
|
|
||||||
class Classify_functor_local_smoothing_preprocessing
|
|
||||||
{
|
|
||||||
const Label_set& m_labels;
|
|
||||||
const Classifier& m_classifier;
|
|
||||||
std::vector<std::vector<float> >& m_values;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Classify_functor_local_smoothing_preprocessing
|
|
||||||
(const Label_set& labels,
|
|
||||||
const Classifier& classifier,
|
|
||||||
std::vector<std::vector<float> >& values)
|
|
||||||
: m_labels (labels), m_classifier (classifier), m_values (values)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
|
||||||
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
|
||||||
{
|
|
||||||
for (std::size_t s = r.begin(); s != r.end(); ++ s)
|
|
||||||
apply (s);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void apply (std::size_t s) const
|
|
||||||
{
|
|
||||||
std::vector<float> values;
|
|
||||||
m_classifier(s, values);
|
|
||||||
for(std::size_t k = 0; k < m_labels.size(); ++ k)
|
|
||||||
m_values[k][s] = values[k];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ItemRange, typename ItemMap, typename NeighborQuery, typename LabelIndexRange>
|
|
||||||
class Classify_functor_local_smoothing
|
|
||||||
{
|
|
||||||
const ItemRange& m_input;
|
|
||||||
const ItemMap m_item_map;
|
|
||||||
const Label_set& m_labels;
|
|
||||||
const std::vector<std::vector<float> >& m_values;
|
|
||||||
const NeighborQuery& m_neighbor_query;
|
|
||||||
LabelIndexRange& m_out;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Classify_functor_local_smoothing (const ItemRange& input,
|
|
||||||
ItemMap item_map,
|
|
||||||
const Label_set& labels,
|
|
||||||
const std::vector<std::vector<float> >& values,
|
|
||||||
const NeighborQuery& neighbor_query,
|
|
||||||
LabelIndexRange& out)
|
|
||||||
: m_input (input), m_item_map (item_map), m_labels (labels),
|
|
||||||
m_values(values),
|
|
||||||
m_neighbor_query (neighbor_query),
|
|
||||||
m_out (out)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
|
||||||
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
|
||||||
{
|
|
||||||
for (std::size_t s = r.begin(); s != r.end(); ++ s)
|
|
||||||
apply (s);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void apply (std::size_t s) const
|
|
||||||
{
|
|
||||||
std::vector<std::size_t> neighbors;
|
|
||||||
m_neighbor_query (get (m_item_map, *(m_input.begin()+s)), std::back_inserter (neighbors));
|
|
||||||
|
|
||||||
std::vector<float> mean (m_values.size(), 0.);
|
|
||||||
for (std::size_t n = 0; n < neighbors.size(); ++ n)
|
|
||||||
for (std::size_t j = 0; j < m_values.size(); ++ j)
|
|
||||||
mean[j] += m_values[j][neighbors[n]];
|
|
||||||
|
|
||||||
std::size_t nb_class_best=0;
|
|
||||||
float val_class_best = 0.f;
|
|
||||||
for(std::size_t k = 0; k < mean.size(); ++ k)
|
|
||||||
{
|
|
||||||
mean[k] /= neighbors.size();
|
|
||||||
if(val_class_best < mean[k])
|
|
||||||
{
|
|
||||||
val_class_best = mean[k];
|
|
||||||
nb_class_best = k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_out[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ItemRange, typename ItemMap,
|
|
||||||
typename Classifier, typename NeighborQuery,
|
|
||||||
typename LabelIndexRange>
|
|
||||||
class Classify_functor_graphcut
|
|
||||||
{
|
|
||||||
const ItemRange& m_input;
|
|
||||||
ItemMap m_item_map;
|
|
||||||
const Label_set& m_labels;
|
|
||||||
const Classifier& m_classifier;
|
|
||||||
const NeighborQuery& m_neighbor_query;
|
|
||||||
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;
|
|
||||||
LabelIndexRange& m_out;
|
|
||||||
|
|
||||||
#ifdef CGAL_DO_NOT_USE_BOYKOV_KOLMOGOROV_MAXFLOW_SOFTWARE
|
|
||||||
typedef CGAL::internal::Alpha_expansion_graph_cut_boost Alpha_expansion;
|
|
||||||
#else
|
|
||||||
typedef CGAL::internal::Alpha_expansion_graph_cut_boykov_kolmogorov Alpha_expansion;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Classify_functor_graphcut (const ItemRange& input,
|
|
||||||
ItemMap item_map,
|
|
||||||
const Label_set& labels,
|
|
||||||
const Classifier& classifier,
|
|
||||||
const NeighborQuery& neighbor_query,
|
|
||||||
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,
|
|
||||||
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)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
#ifdef CGAL_LINKED_WITH_TBB
|
|
||||||
void operator()(const tbb::blocked_range<std::size_t>& r) const
|
|
||||||
{
|
|
||||||
for (std::size_t s = r.begin(); s != r.end(); ++ s)
|
|
||||||
apply(s);
|
|
||||||
}
|
|
||||||
#endif // CGAL_LINKED_WITH_TBB
|
|
||||||
|
|
||||||
|
|
||||||
inline void apply (std::size_t sub) const
|
|
||||||
{
|
|
||||||
if (m_indices[sub].empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::vector<std::pair<std::size_t, std::size_t> > edges;
|
|
||||||
std::vector<double> edge_weights;
|
|
||||||
std::vector<std::vector<double> > probability_matrix
|
|
||||||
(m_labels.size(), std::vector<double>(m_indices[sub].size(), 0.));
|
|
||||||
std::vector<std::size_t> assigned_label (m_indices[sub].size());
|
|
||||||
|
|
||||||
for (std::size_t j = 0; j < m_indices[sub].size(); ++ j)
|
|
||||||
{
|
|
||||||
std::size_t s = m_indices[sub][j];
|
|
||||||
|
|
||||||
std::vector<std::size_t> neighbors;
|
|
||||||
|
|
||||||
m_neighbor_query (get(m_item_map, *(m_input.begin()+s)), std::back_inserter (neighbors));
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < neighbors.size(); ++ i)
|
|
||||||
if (sub == m_input_to_indices[neighbors[i]].first
|
|
||||||
&& j != m_input_to_indices[neighbors[i]].second)
|
|
||||||
{
|
|
||||||
edges.push_back (std::make_pair (j, m_input_to_indices[neighbors[i]].second));
|
|
||||||
edge_weights.push_back (m_strength);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<float> values;
|
|
||||||
m_classifier(s, values);
|
|
||||||
std::size_t nb_class_best = 0;
|
|
||||||
float val_class_best = 0.f;
|
|
||||||
for(std::size_t k = 0; k < m_labels.size(); ++ k)
|
|
||||||
{
|
|
||||||
float value = values[k];
|
|
||||||
probability_matrix[k][j] = -std::log(value);
|
|
||||||
|
|
||||||
if(val_class_best < value)
|
|
||||||
{
|
|
||||||
val_class_best = value;
|
|
||||||
nb_class_best = k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assigned_label[j] = nb_class_best;
|
|
||||||
}
|
|
||||||
|
|
||||||
Alpha_expansion graphcut;
|
|
||||||
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]] = static_cast<typename LabelIndexRange::iterator::value_type>(assigned_label[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
/// \endcond
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\ingroup PkgClassificationMain
|
\ingroup PkgClassificationMain
|
||||||
|
|
||||||
|
|
@ -362,23 +72,28 @@ namespace internal {
|
||||||
const Classifier& classifier,
|
const Classifier& classifier,
|
||||||
LabelIndexRange& output)
|
LabelIndexRange& output)
|
||||||
{
|
{
|
||||||
internal::Classify_functor<Classifier, LabelIndexRange>
|
CGAL::for_each<ConcurrencyTag>
|
||||||
f (labels, classifier, output);
|
(CGAL::make_range (boost::counting_iterator<std::size_t>(0),
|
||||||
|
boost::counting_iterator<std::size_t>(input.size())),
|
||||||
|
[&](const std::size_t& s) -> bool
|
||||||
|
{
|
||||||
|
std::size_t nb_class_best=0;
|
||||||
|
std::vector<float> values;
|
||||||
|
classifier (s, values);
|
||||||
|
|
||||||
#ifndef CGAL_LINKED_WITH_TBB
|
float val_class_best = 0.f;
|
||||||
CGAL_static_assertion_msg (!(std::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
for(std::size_t k = 0; k < labels.size(); ++ k)
|
||||||
"Parallel_tag is enabled but TBB is unavailable.");
|
{
|
||||||
#else
|
if(val_class_best < values[k])
|
||||||
if (std::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
{
|
||||||
{
|
val_class_best = values[k];
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, input.size ()), f);
|
nb_class_best = k;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
#endif
|
output[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < input.size(); ++ i)
|
return true;
|
||||||
f.apply(i);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \cond SKIP_IN_MANUAL
|
/// \cond SKIP_IN_MANUAL
|
||||||
|
|
@ -394,23 +109,30 @@ namespace internal {
|
||||||
LabelIndexRange& output,
|
LabelIndexRange& output,
|
||||||
ProbabilitiesRanges& probabilities)
|
ProbabilitiesRanges& probabilities)
|
||||||
{
|
{
|
||||||
internal::Classify_detailed_output_functor<Classifier, LabelIndexRange, ProbabilitiesRanges>
|
CGAL::for_each<ConcurrencyTag>
|
||||||
f (labels, classifier, output, probabilities);
|
(CGAL::make_range (boost::counting_iterator<std::size_t>(0),
|
||||||
|
boost::counting_iterator<std::size_t>(input.size())),
|
||||||
|
[&](const std::size_t& s) -> bool
|
||||||
|
{
|
||||||
|
std::size_t nb_class_best=0;
|
||||||
|
std::vector<float> values;
|
||||||
|
classifier (s, values);
|
||||||
|
|
||||||
#ifndef CGAL_LINKED_WITH_TBB
|
float val_class_best = 0.f;
|
||||||
CGAL_static_assertion_msg (!(std::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
for(std::size_t k = 0; k < labels.size(); ++ k)
|
||||||
"Parallel_tag is enabled but TBB is unavailable.");
|
{
|
||||||
#else
|
probabilities[k][s] = values[k];
|
||||||
if (std::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
if(val_class_best < values[k])
|
||||||
{
|
{
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, input.size ()), f);
|
val_class_best = values[k];
|
||||||
}
|
nb_class_best = k;
|
||||||
else
|
}
|
||||||
#endif
|
}
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < input.size(); ++ i)
|
output[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
|
||||||
f.apply(i);
|
|
||||||
}
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/// \endcond
|
/// \endcond
|
||||||
|
|
||||||
|
|
@ -460,28 +182,49 @@ namespace internal {
|
||||||
{
|
{
|
||||||
std::vector<std::vector<float> > values
|
std::vector<std::vector<float> > values
|
||||||
(labels.size(), std::vector<float> (input.size(), -1.));
|
(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, LabelIndexRange>
|
|
||||||
f2 (input, item_map, labels, values, neighbor_query, output);
|
|
||||||
|
|
||||||
#ifndef CGAL_LINKED_WITH_TBB
|
CGAL::for_each<ConcurrencyTag>
|
||||||
CGAL_static_assertion_msg (!(std::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
(CGAL::make_range (boost::counting_iterator<std::size_t>(0),
|
||||||
"Parallel_tag is enabled but TBB is unavailable.");
|
boost::counting_iterator<std::size_t>(input.size())),
|
||||||
#else
|
[&](const std::size_t& s) -> bool
|
||||||
if (std::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
{
|
||||||
{
|
std::vector<float> v;
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, input.size ()), f1);
|
classifier(s, v);
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, input.size ()), f2);
|
for(std::size_t k = 0; k < labels.size(); ++ k)
|
||||||
}
|
values[k][s] = v[k];
|
||||||
else
|
|
||||||
#endif
|
return true;
|
||||||
{
|
});
|
||||||
for (std::size_t i = 0; i < input.size(); ++ i)
|
|
||||||
f1.apply(i);
|
CGAL::for_each<ConcurrencyTag>
|
||||||
for (std::size_t i = 0; i < input.size(); ++ i)
|
(CGAL::make_range (boost::counting_iterator<std::size_t>(0),
|
||||||
f2.apply(i);
|
boost::counting_iterator<std::size_t>(input.size())),
|
||||||
}
|
[&](const std::size_t& s) -> bool
|
||||||
|
{
|
||||||
|
std::vector<std::size_t> neighbors;
|
||||||
|
neighbor_query (get (item_map, *(input.begin()+s)), std::back_inserter (neighbors));
|
||||||
|
|
||||||
|
std::vector<float> mean (values.size(), 0.);
|
||||||
|
for (std::size_t n = 0; n < neighbors.size(); ++ n)
|
||||||
|
for (std::size_t j = 0; j < values.size(); ++ j)
|
||||||
|
mean[j] += values[j][neighbors[n]];
|
||||||
|
|
||||||
|
std::size_t nb_class_best=0;
|
||||||
|
float val_class_best = 0.f;
|
||||||
|
for(std::size_t k = 0; k < mean.size(); ++ k)
|
||||||
|
{
|
||||||
|
mean[k] /= neighbors.size();
|
||||||
|
if(val_class_best < mean[k])
|
||||||
|
{
|
||||||
|
val_class_best = mean[k];
|
||||||
|
nb_class_best = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output[s] = static_cast<typename LabelIndexRange::iterator::value_type>(nb_class_best);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -594,23 +337,65 @@ namespace internal {
|
||||||
CGAL_assertion_msg (i != bboxes.size(), "Point was not assigned to any subdivision.");
|
CGAL_assertion_msg (i != bboxes.size(), "Point was not assigned to any subdivision.");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal::Classify_functor_graphcut<ItemRange, ItemMap, Classifier, NeighborQuery, LabelIndexRange>
|
CGAL::for_each<ConcurrencyTag>
|
||||||
f (input, item_map, labels, classifier, neighbor_query, strength, indices, input_to_indices, output);
|
(CGAL::make_range (boost::counting_iterator<std::size_t>(0),
|
||||||
|
boost::counting_iterator<std::size_t>(indices.size())),
|
||||||
|
[&](const std::size_t& sub) -> bool
|
||||||
|
{
|
||||||
|
if (indices[sub].empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
#ifndef CGAL_LINKED_WITH_TBB
|
std::vector<std::pair<std::size_t, std::size_t> > edges;
|
||||||
CGAL_static_assertion_msg (!(std::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
std::vector<double> edge_weights;
|
||||||
"Parallel_tag is enabled but TBB is unavailable.");
|
std::vector<std::vector<double> > probability_matrix
|
||||||
|
(labels.size(), std::vector<double>(indices[sub].size(), 0.));
|
||||||
|
std::vector<std::size_t> assigned_label (indices[sub].size());
|
||||||
|
|
||||||
|
for (std::size_t j = 0; j < indices[sub].size(); ++ j)
|
||||||
|
{
|
||||||
|
std::size_t s = indices[sub][j];
|
||||||
|
|
||||||
|
std::vector<std::size_t> neighbors;
|
||||||
|
|
||||||
|
neighbor_query (get(item_map, *(input.begin()+s)), std::back_inserter (neighbors));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < neighbors.size(); ++ i)
|
||||||
|
if (sub == input_to_indices[neighbors[i]].first
|
||||||
|
&& j != input_to_indices[neighbors[i]].second)
|
||||||
|
{
|
||||||
|
edges.push_back (std::make_pair (j, input_to_indices[neighbors[i]].second));
|
||||||
|
edge_weights.push_back (strength);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<float> values;
|
||||||
|
classifier(s, values);
|
||||||
|
std::size_t nb_class_best = 0;
|
||||||
|
float val_class_best = 0.f;
|
||||||
|
for(std::size_t k = 0; k < labels.size(); ++ k)
|
||||||
|
{
|
||||||
|
float value = values[k];
|
||||||
|
probability_matrix[k][j] = -std::log(value);
|
||||||
|
|
||||||
|
if(val_class_best < value)
|
||||||
|
{
|
||||||
|
val_class_best = value;
|
||||||
|
nb_class_best = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assigned_label[j] = nb_class_best;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CGAL_DO_NOT_USE_BOYKOV_KOLMOGOROV_MAXFLOW_SOFTWARE
|
||||||
|
CGAL::internal::Alpha_expansion_graph_cut_boost graphcut;
|
||||||
#else
|
#else
|
||||||
if (std::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
CGAL::internal::Alpha_expansion_graph_cut_boykov_kolmogorov graphcut;
|
||||||
{
|
|
||||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, indices.size ()), f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
graphcut(edges, edge_weights, probability_matrix, assigned_label);
|
||||||
for (std::size_t sub = 0; sub < indices.size(); ++ sub)
|
|
||||||
f.apply (sub);
|
for (std::size_t i = 0; i < assigned_label.size(); ++ i)
|
||||||
}
|
output[indices[sub][i]] = static_cast<typename LabelIndexRange::iterator::value_type>(assigned_label[i]);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue