1 #ifndef ITEM_CLASSIFICATION_BASE_H
2 #define ITEM_CLASSIFICATION_BASE_H
3 
4 #include <CGAL/Three/Scene_item.h>
5 
6 #include <QComboBox>
7 #include <QLineEdit>
8 #include <QSpinBox>
9 #include <QMultipleInputDialog.h>
10 
11 #include <CGAL/Classification/Feature_set.h>
12 #include <CGAL/Classification/Label_set.h>
13 
14 
15 #include <CGAL/Classification/ETHZ/Random_forest_classifier.h>
16 #include <CGAL/Classification/Sum_of_weighted_features_classifier.h>
17 
18 #ifdef CGAL_LINKED_WITH_OPENCV
19 #  include <CGAL/Classification/OpenCV/Random_forest_classifier.h>
20 #endif
21 
22 #define CGAL_CLASSIFICATION_ETHZ_ID "Random Forest (ETHZ)"
23 #define CGAL_CLASSIFICATION_ETHZ_NUMBER 0
24 
25 #define CGAL_CLASSIFICATION_OPENCV_ID "Random Forest (OpenCV)"
26 #define CGAL_CLASSIFICATION_OPENCV_NUMBER 1
27 
28 #define CGAL_CLASSIFICATION_SOWF_ID "Sum of Weighted Features"
29 #define CGAL_CLASSIFICATION_SOWF_NUMBER 2
30 
31 
32 class Item_classification_base
33 {
34 public:
35   typedef CGAL::Classification::Label_handle   Label_handle;
36   typedef CGAL::Classification::Feature_handle Feature_handle;
37   typedef CGAL::Classification::Label_set   Label_set;
38   typedef CGAL::Classification::Feature_set Feature_set;
39   typedef CGAL::Classification::Sum_of_weighted_features_classifier Sum_of_weighted_features;
40   typedef CGAL::Classification::ETHZ::Random_forest_classifier ETHZ_random_forest;
41 
42 #ifdef CGAL_LINKED_WITH_OPENCV
43   typedef CGAL::Classification::OpenCV::Random_forest_classifier Random_forest;
44 #endif
45 
46 public:
47 
Item_classification_base()48   Item_classification_base() { }
~Item_classification_base()49   virtual ~Item_classification_base() { }
50 
51   virtual CGAL::Three::Scene_item* item() = 0;
52   virtual void erase_item() = 0;
53 
bbox()54   virtual CGAL::Bbox_3 bbox() { return item()->bbox(); }
55 
56   virtual void compute_features (std::size_t nb_scales, float voxel_size) = 0;
57 
feature_statistics()58   virtual std::string feature_statistics () const { return std::string(); }
59 
60   virtual void add_selection_to_training_set (std::size_t label) = 0;
61   virtual void reset_training_set (std::size_t label) = 0;
62   virtual void reset_training_set_of_selection() = 0;
63   virtual void reset_training_sets() = 0;
64 
65   virtual void select_random_region() = 0;
66   virtual void validate_selection () = 0;
67   virtual void train(int classifier, const QMultipleInputDialog&) = 0;
68   virtual bool run (int method, int classifier, std::size_t subdivisions, double smoothing) = 0;
69 
70   virtual void update_color () = 0;
71   virtual void change_color (int index, float* vmin = nullptr, float* vmax = nullptr) = 0;
72   virtual CGAL::Three::Scene_item* generate_one_item (const char* name,
73                                                       int label) const = 0;
74   virtual void generate_one_item_per_label(std::vector<CGAL::Three::Scene_item*>& items,
75                                            const char* name) const = 0;
76 
features_computed()77   bool features_computed() const { return (m_features.size() != 0); }
number_of_features()78   std::size_t number_of_features() const { return m_features.size(); }
feature(std::size_t i)79   Feature_handle feature(std::size_t i) { return m_features[i]; }
weight(Feature_handle f)80   float weight (Feature_handle f) const { return m_sowf->weight(f); }
set_weight(Feature_handle f,float w)81   void set_weight (Feature_handle f, float w) const { m_sowf->set_weight(f,w); }
effect(Label_handle l,Feature_handle f)82   Sum_of_weighted_features::Effect effect (Label_handle l, Feature_handle f) const { return m_sowf->effect(l,f); }
set_effect(Label_handle l,Feature_handle f,Sum_of_weighted_features::Effect e)83   void set_effect (Label_handle l, Feature_handle f, Sum_of_weighted_features::Effect e)
84   { m_sowf->set_effect (l, f, e); }
85 
label_qcolor(Label_handle l)86   QColor label_qcolor (Label_handle l) const
87   {
88     return QColor (l->color().red(), l->color().green(), l->color().blue());
89   }
90 
add_new_label(const char * name)91   virtual QColor add_new_label (const char* name)
92   {
93     m_labels.add(name);
94 
95     delete m_sowf;
96     m_sowf = new Sum_of_weighted_features (m_labels, m_features);
97 
98     delete m_ethz;
99     m_ethz = new ETHZ_random_forest (m_labels, m_features);
100 
101 #ifdef CGAL_LINKED_WITH_OPENCV
102     delete m_random_forest;
103     m_random_forest = new Random_forest (m_labels, m_features);
104 #endif
105 
106     return label_qcolor (m_labels[m_labels.size() - 1]);
107   }
remove_label(std::size_t position)108   virtual void remove_label (std::size_t position)
109   {
110     m_labels.remove(m_labels[position]);
111 
112     delete m_sowf;
113     m_sowf = new Sum_of_weighted_features (m_labels, m_features);
114 
115     delete m_ethz;
116     m_ethz = new ETHZ_random_forest (m_labels, m_features);
117 
118 #ifdef CGAL_LINKED_WITH_OPENCV
119     delete m_random_forest;
120     m_random_forest = new Random_forest (m_labels, m_features);
121 #endif
122 
123   }
124 
clear_labels()125   virtual void clear_labels ()
126   {
127     m_labels.clear();
128 
129     delete m_sowf;
130     m_sowf = new Sum_of_weighted_features (m_labels, m_features);
131 
132     delete m_ethz;
133     m_ethz = new ETHZ_random_forest (m_labels, m_features);
134 
135 #ifdef CGAL_LINKED_WITH_OPENCV
136     delete m_random_forest;
137     m_random_forest = new Random_forest (m_labels, m_features);
138 #endif
139 
140   }
number_of_labels()141   std::size_t number_of_labels() const { return m_labels.size(); }
label(std::size_t i)142   Label_handle label(std::size_t i) { return m_labels[i]; }
143 
fill_display_combo_box(QComboBox * cb,QComboBox * cb1)144   virtual void fill_display_combo_box (QComboBox* cb, QComboBox* cb1) const
145   {
146     for (std::size_t i = 0; i < m_labels.size(); ++ i)
147       {
148         std::ostringstream oss;
149         oss << "Label " << m_labels[i]->name();
150         cb->addItem (oss.str().c_str());
151         cb1->addItem (oss.str().c_str());
152       }
153     for (std::size_t i = 0; i < m_features.size(); ++ i)
154       {
155         std::ostringstream oss;
156         oss << "Feature " << m_features[i]->name();
157         cb->addItem (oss.str().c_str());
158         cb1->addItem (oss.str().c_str());
159       }
160   }
161 
save_config(const char * filename,int classifier)162   void save_config(const char* filename, int classifier)
163   {
164     if (m_features.size() == 0)
165       {
166         std::cerr << "Error: features not computed" << std::endl;
167         return;
168       }
169 
170     if (classifier == CGAL_CLASSIFICATION_SOWF_NUMBER)
171     {
172       std::ofstream f (filename);
173       m_sowf->save_configuration (f);
174     }
175     else if (classifier == CGAL_CLASSIFICATION_ETHZ_NUMBER)
176     {
177       std::cerr << "D ";
178       std::ofstream f (filename, std::ios_base::out | std::ios_base::binary);
179       m_ethz->save_configuration (f);
180       std::cerr << "E ";
181     }
182     else if (classifier == CGAL_CLASSIFICATION_OPENCV_NUMBER)
183     {
184 #ifdef CGAL_LINKED_WITH_OPENCV
185       m_random_forest->save_configuration (filename);
186 #endif
187     }
188   }
load_config(const char * filename,int classifier)189   void load_config(const char* filename, int classifier)
190   {
191     if (m_features.size() == 0)
192       {
193         std::cerr << "Error: features not computed" << std::endl;
194         return;
195       }
196 
197     if (classifier == CGAL_CLASSIFICATION_SOWF_NUMBER)
198     {
199       std::ifstream f (filename);
200       m_sowf->load_configuration (f, true);
201     }
202     else if (classifier == CGAL_CLASSIFICATION_ETHZ_NUMBER)
203     {
204       if (m_ethz == nullptr)
205         m_ethz = new ETHZ_random_forest (m_labels, m_features);
206       std::ifstream f (filename, std::ios_base::in | std::ios_base::binary);
207 
208 #if defined(CGAL_LINKED_WITH_BOOST_IOSTREAMS) && defined(CGAL_LINKED_WITH_BOOST_SERIALIZATION)
209       // Handle deprecated files
210       if (std::string(filename).find(".gz") != std::string::npos)
211         m_ethz->load_deprecated_configuration(f);
212       else
213 #endif
214         m_ethz->load_configuration (f);
215     }
216     else if (classifier == CGAL_CLASSIFICATION_OPENCV_NUMBER)
217     {
218 #ifdef CGAL_LINKED_WITH_OPENCV
219       m_random_forest->load_configuration (filename);
220 #endif
221     }
222   }
223 
label_color(std::size_t i)224   QColor label_color(std::size_t i) const
225   {
226     return label_qcolor (m_labels[i]);
227   }
change_label_color(std::size_t position,const QColor & color)228   void change_label_color (std::size_t position, const QColor& color)
229   {
230     m_labels[position]->set_color
231       (CGAL::IO::Color (color.red(), color.green(), color.blue()));
232   }
change_label_name(std::size_t position,const std::string & name)233   void change_label_name (std::size_t position, const std::string& name)
234   {
235     m_labels[position]->set_name (name);
236   }
237 
238 protected:
239 
240   Label_set m_labels;
241   Feature_set m_features;
242   Sum_of_weighted_features* m_sowf;
243   ETHZ_random_forest* m_ethz;
244 #ifdef CGAL_LINKED_WITH_OPENCV
245   Random_forest* m_random_forest;
246 #endif
247 
248 };
249 
250 
251 
252 
253 #endif // ITEM_CLASSIFICATION_BASE_H
254