mirror of https://github.com/CGAL/cgal
Many improvements for plugin, statistics on features, etc.
This commit is contained in:
parent
335375dbba
commit
4bebcae4f2
|
|
@ -210,6 +210,10 @@ public:
|
|||
connect(compute_features, SIGNAL(triggered()), this,
|
||||
SLOT(on_compute_features_button_clicked()));
|
||||
|
||||
action_statistics = ui_widget.menu->menu()->addAction ("Show feature statistics");
|
||||
connect(action_statistics, SIGNAL(triggered()), this,
|
||||
SLOT(on_statistics_clicked()));
|
||||
|
||||
ui_widget.menu->menu()->addSection ("Training");
|
||||
|
||||
action_train = ui_widget.menu->menu()->addAction ("Train classifier");
|
||||
|
|
@ -264,6 +268,11 @@ public:
|
|||
connect(ui_widget.display, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(on_display_button_clicked(int)));
|
||||
|
||||
connect(ui_widget.minDisplay, SIGNAL(released()), this,
|
||||
SLOT(on_min_display_button_clicked()));
|
||||
connect(ui_widget.maxDisplay, SIGNAL(released()), this,
|
||||
SLOT(on_max_display_button_clicked()));
|
||||
|
||||
connect(ui_widget_adv.selected_feature, SIGNAL(currentIndexChanged(int)), this,
|
||||
SLOT(on_selected_feature_changed(int)));
|
||||
connect(ui_widget_adv.feature_weight, SIGNAL(valueChanged(int)), this,
|
||||
|
|
@ -278,6 +287,7 @@ public:
|
|||
connect(scene_obj, SIGNAL(itemIndexSelected(int)), this,
|
||||
SLOT(update_plugin(int)));
|
||||
}
|
||||
|
||||
}
|
||||
virtual void closure()
|
||||
{
|
||||
|
|
@ -359,6 +369,7 @@ public Q_SLOTS:
|
|||
void enable_computation()
|
||||
{
|
||||
ui_widget.menu->setEnabled(true);
|
||||
action_statistics->setEnabled(false);
|
||||
action_train->setEnabled(false);
|
||||
action_reset_local->setEnabled(false);
|
||||
action_reset->setEnabled(false);
|
||||
|
|
@ -375,6 +386,7 @@ public Q_SLOTS:
|
|||
|
||||
void enable_classif()
|
||||
{
|
||||
action_statistics->setEnabled(true);
|
||||
action_train->setEnabled(true);
|
||||
action_reset_local->setEnabled(true);
|
||||
action_reset->setEnabled(true);
|
||||
|
|
@ -428,9 +440,15 @@ public Q_SLOTS:
|
|||
ui_widget_adv.selected_feature->clear();
|
||||
classif->fill_display_combo_box(ui_widget.display, ui_widget_adv.selected_feature);
|
||||
if (index >= ui_widget.display->count())
|
||||
{
|
||||
ui_widget.display->setCurrentIndex(1);
|
||||
change_color (classif, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_widget.display->setCurrentIndex(index);
|
||||
change_color (classif, index);
|
||||
}
|
||||
ui_widget_adv.selected_feature->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -556,17 +574,26 @@ public Q_SLOTS:
|
|||
return;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
int nb_scales = QInputDialog::getInt((QWidget*)mw,
|
||||
tr("Compute Features"), // dialog title
|
||||
tr("Number of scales:"), // field label
|
||||
5, 1, 99, 1, &ok);
|
||||
if (!ok)
|
||||
QMultipleInputDialog dialog ("Compute Features", mw);
|
||||
QSpinBox* scales = dialog.add<QSpinBox> ("Number of scales:");
|
||||
scales->setRange (1, 99);
|
||||
scales->setValue (5);
|
||||
|
||||
QDoubleSpinBox* voxel_size = dialog.add<QDoubleSpinBox> ("Voxel size (0 for automatic):");
|
||||
voxel_size->setRange (0.0, 10000.0);
|
||||
voxel_size->setValue (0.0);
|
||||
voxel_size->setSingleStep (0.01);
|
||||
|
||||
if (dialog.exec() != QDialog::Accepted)
|
||||
return;
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
|
||||
classif->compute_features (std::size_t(nb_scales));
|
||||
float vsize = float(voxel_size->value());
|
||||
if (vsize == 0.f)
|
||||
vsize = -1.f; // auto value
|
||||
|
||||
classif->compute_features (std::size_t(scales->value()), vsize);
|
||||
|
||||
update_plugin_from_item(classif);
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
|
@ -683,7 +710,32 @@ public Q_SLOTS:
|
|||
item_changed(classif->item());
|
||||
}
|
||||
|
||||
void change_color (Item_classification_base* classif, int index)
|
||||
{
|
||||
float vmin = std::numeric_limits<float>::infinity();
|
||||
float vmax = std::numeric_limits<float>::infinity();
|
||||
|
||||
classif->change_color (index, &vmin, &vmax);
|
||||
|
||||
if (vmin == std::numeric_limits<float>::infinity() || vmax == std::numeric_limits<float>::infinity())
|
||||
{
|
||||
ui_widget.minDisplay->setEnabled(false);
|
||||
ui_widget.minDisplay->setText("Min");
|
||||
ui_widget.maxDisplay->setEnabled(false);
|
||||
ui_widget.maxDisplay->setText("Max");
|
||||
}
|
||||
else
|
||||
{
|
||||
ui_widget.minDisplay->setEnabled(true);
|
||||
ui_widget.minDisplay->setText(tr("Min (%1)").arg(vmin));
|
||||
ui_widget.maxDisplay->setEnabled(true);
|
||||
ui_widget.maxDisplay->setText(tr("Max (%1)").arg(vmax));
|
||||
}
|
||||
|
||||
item_changed(classif->item());
|
||||
}
|
||||
|
||||
|
||||
void on_display_button_clicked(int index)
|
||||
{
|
||||
Item_classification_base* classif
|
||||
|
|
@ -691,7 +743,87 @@ public Q_SLOTS:
|
|||
if(!classif)
|
||||
return;
|
||||
|
||||
classif->change_color (index);
|
||||
change_color (classif, index);
|
||||
}
|
||||
|
||||
float display_button_value (QPushButton* button)
|
||||
{
|
||||
std::string text = button->text().toStdString();
|
||||
|
||||
std::size_t pos1 = text.find('(');
|
||||
if (pos1 == std::string::npos)
|
||||
return std::numeric_limits<float>::infinity();
|
||||
std::size_t pos2 = text.find(')');
|
||||
if (pos2 == std::string::npos)
|
||||
return std::numeric_limits<float>::infinity();
|
||||
|
||||
std::string fstring (text.begin() + pos1 + 1,
|
||||
text.begin() + pos2);
|
||||
|
||||
return float (std::atof(fstring.c_str()));
|
||||
}
|
||||
|
||||
void on_min_display_button_clicked()
|
||||
{
|
||||
Item_classification_base* classif
|
||||
= get_classification();
|
||||
if(!classif)
|
||||
return;
|
||||
|
||||
float vmin = display_button_value (ui_widget.minDisplay);
|
||||
float vmax = display_button_value (ui_widget.maxDisplay);
|
||||
|
||||
if (vmin == std::numeric_limits<float>::infinity()
|
||||
|| vmax == std::numeric_limits<float>::infinity())
|
||||
return;
|
||||
|
||||
bool ok = false;
|
||||
vmin = float(QInputDialog::getDouble((QWidget*)mw,
|
||||
tr("Set display ramp minimum value (saturate under):"),
|
||||
tr("Minimum value (pale blue):"),
|
||||
double(vmin),
|
||||
-10000000.0,
|
||||
double(vmax), 5, &ok));
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
int index = ui_widget.display->currentIndex();
|
||||
|
||||
classif->change_color (index, &vmin, &vmax);
|
||||
ui_widget.minDisplay->setText(tr("Min* (%1)").arg(vmin));
|
||||
|
||||
item_changed(classif->item());
|
||||
}
|
||||
|
||||
void on_max_display_button_clicked()
|
||||
{
|
||||
Item_classification_base* classif
|
||||
= get_classification();
|
||||
if(!classif)
|
||||
return;
|
||||
|
||||
float vmin = display_button_value (ui_widget.minDisplay);
|
||||
float vmax = display_button_value (ui_widget.maxDisplay);
|
||||
|
||||
if (vmin == std::numeric_limits<float>::infinity()
|
||||
|| vmax == std::numeric_limits<float>::infinity())
|
||||
return;
|
||||
|
||||
bool ok = false;
|
||||
vmax = float(QInputDialog::getDouble((QWidget*)mw,
|
||||
tr("Set display ramp maximum value (saturate over):"),
|
||||
tr("Maximum value (dark red):"),
|
||||
double(vmax),
|
||||
double(vmin),
|
||||
10000000.0, 5, &ok));
|
||||
if (!ok)
|
||||
return;
|
||||
|
||||
int index = ui_widget.display->currentIndex();
|
||||
|
||||
classif->change_color (index, &vmin, &vmax);
|
||||
ui_widget.maxDisplay->setText(tr("Max* (%1)").arg(vmax));
|
||||
|
||||
item_changed(classif->item());
|
||||
}
|
||||
|
||||
|
|
@ -1104,6 +1236,26 @@ public Q_SLOTS:
|
|||
(bbox.zmin() + bbox.zmax()) / 2.) + offset);
|
||||
}
|
||||
|
||||
void on_statistics_clicked()
|
||||
{
|
||||
Item_classification_base* classif
|
||||
= get_classification();
|
||||
if(!classif)
|
||||
{
|
||||
print_message("Error: there is no point set classification item!");
|
||||
return;
|
||||
}
|
||||
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
std::string str = classif->feature_statistics();
|
||||
QApplication::restoreOverrideCursor();
|
||||
|
||||
QMultipleInputDialog dialog ("Feature Statistics", mw);
|
||||
QLabel* text = dialog.add<QLabel> ("");
|
||||
text->setText(str.c_str());
|
||||
dialog.exec_no_cancel();
|
||||
}
|
||||
|
||||
void on_train_clicked()
|
||||
{
|
||||
Item_classification_base* classif
|
||||
|
|
@ -1457,6 +1609,7 @@ private:
|
|||
|
||||
QDockWidget* dock_widget;
|
||||
QDockWidget* dock_widget_adv;
|
||||
QAction* action_statistics;
|
||||
QAction* action_train;
|
||||
QAction* action_reset_local;
|
||||
QAction* action_reset;
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>289</width>
|
||||
<height>154</height>
|
||||
<width>368</width>
|
||||
<height>143</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
|
@ -20,21 +20,49 @@
|
|||
<string>Classification</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="menu">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Classification</string>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="menu">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Classification</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Classifier:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="classifier">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
|
|
@ -44,63 +72,87 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>View:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="display">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Real colors</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>View:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="display">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Real colors</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Classification</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Training sets</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Classification</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="minDisplay">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Min</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="maxDisplay">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Training sets</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Classifier:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="classifier">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ bool Cluster_classification::write_output(std::ostream& stream)
|
|||
}
|
||||
|
||||
|
||||
void Cluster_classification::change_color (int index)
|
||||
void Cluster_classification::change_color (int index, float* vmin, float* vmax)
|
||||
{
|
||||
m_index_color = index;
|
||||
|
||||
|
|
@ -591,13 +591,18 @@ void Cluster_classification::reset_indices ()
|
|||
*(indices.begin() + i) = idx ++;
|
||||
}
|
||||
|
||||
void Cluster_classification::compute_features (std::size_t nb_scales)
|
||||
void Cluster_classification::compute_features (std::size_t nb_scales, float voxel_size)
|
||||
{
|
||||
CGAL_assertion (!(m_points->point_set()->empty()));
|
||||
|
||||
reset_indices();
|
||||
|
||||
std::cerr << "Computing pointwise features with " << nb_scales << " scale(s)" << std::endl;
|
||||
std::cerr << "Computing pointwise features with " << nb_scales << " scale(s) and ";
|
||||
if (voxel_size == -1)
|
||||
std::cerr << "automatic voxel size" << std::endl;
|
||||
else
|
||||
std::cerr << "voxel size = " << voxel_size << std::endl;
|
||||
|
||||
m_features.clear();
|
||||
|
||||
Point_set::Vector_map normal_map;
|
||||
|
|
@ -615,7 +620,7 @@ void Cluster_classification::compute_features (std::size_t nb_scales)
|
|||
|
||||
Feature_set pointwise_features;
|
||||
|
||||
Generator generator (*(m_points->point_set()), m_points->point_set()->point_map(), nb_scales);
|
||||
Generator generator (*(m_points->point_set()), m_points->point_set()->point_map(), nb_scales, voxel_size);
|
||||
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class Cluster_classification : public Item_classification_base
|
|||
xcenter + dx, ycenter + dy, zcenter + dz);
|
||||
}
|
||||
|
||||
void compute_features (std::size_t nb_scales);
|
||||
void compute_features (std::size_t nb_scales, float voxel_size);
|
||||
void add_remaining_point_set_properties_as_features(Feature_set& feature_set);
|
||||
|
||||
void select_random_region();
|
||||
|
|
@ -206,7 +206,7 @@ class Cluster_classification : public Item_classification_base
|
|||
bool run (int method, int classifier, std::size_t subdivisions, double smoothing);
|
||||
|
||||
void update_color () { change_color (m_index_color); }
|
||||
void change_color (int index);
|
||||
void change_color (int index, float* vmin = NULL, float* vmax = NULL);
|
||||
CGAL::Three::Scene_item* generate_one_item (const char* name,
|
||||
int label) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -45,8 +45,10 @@ public:
|
|||
|
||||
virtual CGAL::Bbox_3 bbox() { return item()->bbox(); }
|
||||
|
||||
virtual void compute_features (std::size_t nb_scales) = 0;
|
||||
virtual void compute_features (std::size_t nb_scales, float voxel_size) = 0;
|
||||
|
||||
virtual std::string feature_statistics () const { return std::string(); }
|
||||
|
||||
virtual void add_selection_to_training_set (std::size_t label) = 0;
|
||||
virtual void reset_training_set (std::size_t label) = 0;
|
||||
virtual void reset_training_set_of_selection() = 0;
|
||||
|
|
@ -58,7 +60,7 @@ public:
|
|||
virtual bool run (int method, int classifier, std::size_t subdivisions, double smoothing) = 0;
|
||||
|
||||
virtual void update_color () = 0;
|
||||
virtual void change_color (int index) = 0;
|
||||
virtual void change_color (int index, float* vmin = NULL, float* vmax = NULL) = 0;
|
||||
virtual CGAL::Three::Scene_item* generate_one_item (const char* name,
|
||||
int label) const = 0;
|
||||
virtual void generate_one_item_per_label(std::vector<CGAL::Three::Scene_item*>& items,
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ bool Point_set_item_classification::write_output(std::ostream& stream)
|
|||
}
|
||||
|
||||
|
||||
void Point_set_item_classification::change_color (int index)
|
||||
void Point_set_item_classification::change_color (int index, float* vmin, float* vmax)
|
||||
{
|
||||
m_index_color = index;
|
||||
|
||||
|
|
@ -425,28 +425,44 @@ void Point_set_item_classification::change_color (int index)
|
|||
return;
|
||||
}
|
||||
Feature_handle feature = m_features[corrected_index];
|
||||
|
||||
|
||||
float min = std::numeric_limits<float>::max();
|
||||
float max = -std::numeric_limits<float>::max();
|
||||
|
||||
for (Point_set::const_iterator it = m_points->point_set()->begin();
|
||||
it != m_points->point_set()->first_selected(); ++ it)
|
||||
|
||||
if (vmin != NULL && vmax != NULL
|
||||
&& *vmin != std::numeric_limits<float>::infinity()
|
||||
&& *vmax != std::numeric_limits<float>::infinity())
|
||||
{
|
||||
if (feature->value(*it) > max)
|
||||
max = feature->value(*it);
|
||||
if (feature->value(*it) < min)
|
||||
min = feature->value(*it);
|
||||
min = *vmin;
|
||||
max = *vmax;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Point_set::const_iterator it = m_points->point_set()->begin();
|
||||
it != m_points->point_set()->end(); ++ it)
|
||||
{
|
||||
float v = feature->value(*it);
|
||||
min = (std::min) (min, v);
|
||||
max = (std::max) (max, v);
|
||||
}
|
||||
}
|
||||
std::cerr << "[Feature " << feature->name() << "] between " << min << " and " << max << std::endl;
|
||||
|
||||
for (Point_set::const_iterator it = m_points->point_set()->begin();
|
||||
it != m_points->point_set()->first_selected(); ++ it)
|
||||
{
|
||||
float v = (feature->value(*it) - min) / (max - min);
|
||||
if (v < 0.f) v = 0.f;
|
||||
if (v > 1.f) v = 1.f;
|
||||
m_red[*it] = (unsigned char)(ramp.r(v) * 255);
|
||||
m_green[*it] = (unsigned char)(ramp.g(v) * 255);
|
||||
m_blue[*it] = (unsigned char)(ramp.b(v) * 255);
|
||||
}
|
||||
|
||||
if (vmin != NULL && vmax != NULL)
|
||||
{
|
||||
*vmin = min;
|
||||
*vmax = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -481,7 +497,7 @@ void Point_set_item_classification::reset_indices ()
|
|||
*(indices.begin() + i) = idx ++;
|
||||
}
|
||||
|
||||
void Point_set_item_classification::compute_features (std::size_t nb_scales)
|
||||
void Point_set_item_classification::compute_features (std::size_t nb_scales, float voxel_size)
|
||||
{
|
||||
CGAL_assertion (!(m_points->point_set()->empty()));
|
||||
|
||||
|
|
@ -490,7 +506,12 @@ void Point_set_item_classification::compute_features (std::size_t nb_scales)
|
|||
|
||||
reset_indices();
|
||||
|
||||
std::cerr << "Computing features with " << nb_scales << " scale(s)" << std::endl;
|
||||
std::cerr << "Computing features with " << nb_scales << " scale(s) and ";
|
||||
if (voxel_size == -1)
|
||||
std::cerr << "automatic voxel size" << std::endl;
|
||||
else
|
||||
std::cerr << "voxel size = " << voxel_size << std::endl;
|
||||
|
||||
m_features.clear();
|
||||
|
||||
Point_set::Vector_map normal_map;
|
||||
|
|
@ -506,7 +527,7 @@ void Point_set_item_classification::compute_features (std::size_t nb_scales)
|
|||
if (!echo)
|
||||
boost::tie (echo_map, echo) = m_points->point_set()->template property_map<boost::uint8_t>("number_of_returns");
|
||||
|
||||
m_generator = new Generator (*(m_points->point_set()), m_points->point_set()->point_map(), nb_scales);
|
||||
m_generator = new Generator (*(m_points->point_set()), m_points->point_set()->point_map(), nb_scales, voxel_size);
|
||||
|
||||
CGAL::Real_timer t;
|
||||
t.start();
|
||||
|
|
|
|||
|
|
@ -117,7 +117,35 @@ class Point_set_item_classification : public Item_classification_base
|
|||
xcenter + dx, ycenter + dy, zcenter + dz);
|
||||
}
|
||||
|
||||
void compute_features (std::size_t nb_scales);
|
||||
void compute_features (std::size_t nb_scales, float voxel_size);
|
||||
|
||||
std::string feature_statistics() const
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
||||
for (std::size_t i = 0; i < m_features.size(); ++ i)
|
||||
{
|
||||
float vmin = std::numeric_limits<float>::max();
|
||||
float vmax = -std::numeric_limits<float>::max();
|
||||
float vmean = 0.f;
|
||||
std::size_t nb = 0;
|
||||
|
||||
for (Point_set::const_iterator it = m_points->point_set()->begin_or_selection_begin();
|
||||
it != m_points->point_set()->end(); ++ it)
|
||||
{
|
||||
float v = m_features[i]->value(std::size_t(it - m_points->point_set()->begin()));
|
||||
vmin = (std::min) (vmin, v);
|
||||
vmax = (std::max) (vmax, v);
|
||||
vmean += v;
|
||||
++ nb;
|
||||
}
|
||||
|
||||
oss << m_features[i]->name() << " in [ " << vmin << " ; " << vmax << " ], mean = " << vmean / nb << std::endl;
|
||||
}
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
void add_remaining_point_set_properties_as_features();
|
||||
|
||||
void select_random_region();
|
||||
|
|
@ -195,7 +223,7 @@ class Point_set_item_classification : public Item_classification_base
|
|||
bool run (int method, int classifier, std::size_t subdivisions, double smoothing);
|
||||
|
||||
void update_color () { change_color (m_index_color); }
|
||||
void change_color (int index);
|
||||
void change_color (int index, float* vmin = NULL, float* vmax = NULL);
|
||||
CGAL::Three::Scene_item* generate_one_item (const char* name,
|
||||
int label) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ bool Surface_mesh_item_classification::write_output(std::ostream& )
|
|||
}
|
||||
|
||||
|
||||
void Surface_mesh_item_classification::change_color (int index)
|
||||
void Surface_mesh_item_classification::change_color (int index, float* vmin, float* vmax)
|
||||
{
|
||||
m_index_color = index;
|
||||
int index_color = index;
|
||||
|
|
@ -198,9 +198,14 @@ void Surface_mesh_item_classification::change_color (int index)
|
|||
}
|
||||
}
|
||||
|
||||
void Surface_mesh_item_classification::compute_features (std::size_t nb_scales)
|
||||
void Surface_mesh_item_classification::compute_features (std::size_t nb_scales, float voxel_size)
|
||||
{
|
||||
std::cerr << "Computing features with " << nb_scales << " scale(s)" << std::endl;
|
||||
std::cerr << "Computing features with " << nb_scales << " scale(s) and ";
|
||||
if (voxel_size == -1)
|
||||
std::cerr << "automatic voxel size" << std::endl;
|
||||
else
|
||||
std::cerr << "voxel size = " << voxel_size << std::endl;
|
||||
|
||||
m_features.clear();
|
||||
|
||||
if (m_generator != NULL)
|
||||
|
|
@ -208,7 +213,7 @@ void Surface_mesh_item_classification::compute_features (std::size_t nb_scales)
|
|||
|
||||
Face_center_map fc_map (m_mesh->polyhedron());
|
||||
|
||||
m_generator = new Generator (*(m_mesh->polyhedron()), fc_map, nb_scales);
|
||||
m_generator = new Generator (*(m_mesh->polyhedron()), fc_map, nb_scales, voxel_size);
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
m_features.begin_parallel_additions();
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public:
|
|||
CGAL::Three::Scene_item* item() { return m_mesh; }
|
||||
void erase_item() { m_mesh = NULL; }
|
||||
|
||||
void compute_features (std::size_t nb_scales);
|
||||
void compute_features (std::size_t nb_scales, float voxel_size);
|
||||
|
||||
void add_selection_to_training_set (std::size_t label)
|
||||
{
|
||||
|
|
@ -120,7 +120,7 @@ public:
|
|||
bool run (int method, int classifier, std::size_t subdivisions, double smoothing);
|
||||
|
||||
void update_color() { change_color (m_index_color); }
|
||||
void change_color (int index);
|
||||
void change_color (int index, float* vmin = NULL, float* vmax = NULL);
|
||||
CGAL::Three::Scene_item* generate_one_item (const char* /* name */,
|
||||
int /* label */) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -63,6 +63,16 @@ public:
|
|||
|
||||
return dialog->exec();
|
||||
}
|
||||
|
||||
void exec_no_cancel()
|
||||
{
|
||||
QDialogButtonBox* ok = new QDialogButtonBox
|
||||
(QDialogButtonBox::Ok, Qt::Horizontal, dialog);
|
||||
|
||||
form->addRow (ok);
|
||||
QObject::connect (ok, SIGNAL(accepted()), dialog, SLOT(accept()));
|
||||
dialog->exec();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue