bazar  1.3.1
image_classification_node.cpp
Go to the documentation of this file.
1 /*
2 Copyright 2005, 2006 Computer Vision Lab,
3 Ecole Polytechnique Federale de Lausanne (EPFL), Switzerland.
4 All rights reserved.
5 
6 This file is part of BazAR.
7 
8 BazAR is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
11 version.
12 
13 BazAR is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 BazAR; if not, write to the Free Software Foundation, Inc., 51 Franklin
19 Street, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21 #include <assert.h>
22 
23 #include <starter.h>
25 
27 {
28  depth = -1;
29  class_number = -1;
30  parent = 0;
31  P = 0;
32 
33  leaf = true;
34 
35  examples = 0;
36 }
37 
38 image_classification_node::image_classification_node(int _depth, int _class_number, image_classification_node * _parent) : children_number(2)
39 {
40  depth = _depth;
41  class_number = _class_number;
42  parent = _parent;
43 
44  leaf = true;
45 
46  examples = 0;
47  P = 0;
48 }
49 
51 {
52  if (examples) delete examples;
53  if (P) delete[] P;
54 
55  if (!is_leaf())
56  for(int i = 0; i < children_number; i++)
57  delete children[i];
58 }
59 
61 {
62  if (examples == 0)
63  examples = new vector<image_class_example *>;
64  examples->push_back(pv);
65 }
66 
68 {
69  if (nb_examples() < 2)
70  return true;
71 
72  // Return true if only one class is present in the examples:
74  int first_represented_class_index = 0;
75  for(vector<image_class_example *>::iterator it = examples->begin(); it < examples->end(); it++)
76  {
77  if (represented_class_number == 0)
78  {
79  first_represented_class_index = (*it)->class_index;
80  represented_class_number = 1;
81  }
82  else
83  if ((*it)->class_index != first_represented_class_index)
84  return false;
85  }
86 
87  return true;
88 }
89 
91 {
92  P = new float[class_number];
93 
94  for(int i = 0; i < class_number; i++)
95  P[i] = 0.;
96 
97  if (nb_examples() > 0)
98  {
99  for(vector<image_class_example *>::iterator it = examples->begin(); it < examples->end(); it++)
100  P[(*it)->class_index]++;
101 
102  for(int i = 0; i < class_number; i++)
103  P[i] /= examples->size();
104  }
105 
106  best_class = 0;
107  float best_p = P[best_class];
108  for(int i = 0; i < class_number; i++)
109  {
110  if (P[i] > best_p)
111  {
112  best_p = P[i];
113  best_class = i;
114  }
115  }
116 }
117 
119 {
120  assert(children_number <= 3);
121 
122  for(int i = 0; i < children_number; i++)
124 
125  if (examples != 0)
126  {
127  for(vector<image_class_example *>::iterator it = examples->begin(); it < examples->end(); it++)
128  for(int i = 0; i < children_number; i++)
129  if (fall_in_child(*it, i))
130  children[i]->add_example(*it);
131 
132  delete examples;
133 
134  examples = 0;
135  }
136 }
137 
139 {
140  int dp = dot_product(pv);
141 
142  if (dp <= 0 && child_index == 0) return true;
143  if (dp > 0 && child_index == 1) return true;
144 
145  return false;
146 }
147 
149 {
150  unsigned char * I = mcvRow(pv->preprocessed, 0, unsigned char);
151  return (int)I[d1] - (int)I[d2];
152 }
153 
155 {
156  int dp = dot_product(pv);
157  if (dp <= 0) return 0;
158 
159  return 1;
160 }
161 
163 {
164  for(int i = 0; i < children_number; i++)
165  {
167  children[i]->P = new float[class_number];
168  for(int j = 0; j < class_number; j++)
169  children[i]->P[j] = 0.;
170  }
171 }
172 
174 {
175  class_number = new_class_number;
176 
177  if (is_leaf())
178  {
179  delete [] P;
180 
181  P = new float[class_number];
182 
183  for(int i = 0; i < class_number; i++)
184  P[i] = 0.;
185  }
186  else
187  for(int i = 0; i < children_number; i++)
189 }
190 
192 {
193  if (is_leaf())
194  {
195  if (weights == 0)
196  {
197  probability_sum = 0;
198 
199  for(int i = 0; i < class_number; i++)
200  probability_sum += P[i];
201 
202  for(int i = 0; i < class_number; i++)
203  P[i] = (probability_sum > 0) ? P[i] / probability_sum : 0.f;
204  }
205  else
206  {
207  probability_sum = 0;
208 
209  for(int i = 0; i < class_number; i++)
210  probability_sum += weights[i] * P[i];
211 
212  for(int i = 0; i < class_number; i++)
213  P[i] = (probability_sum > 0) ? weights[i] * P[i] / probability_sum : 0.f;
214  }
215 
216  best_class = 0;
217  float best_p = P[best_class];
218  for(int i = 0; i < class_number; i++)
219  if (P[i] > best_p)
220  {
221  best_p = P[i];
222  best_class = i;
223  }
224  }
225  else
226  for(int i = 0; i < children_number; i++)
228 }
229 
231 {
232  if (is_leaf())
233  {
234  if (weights == 0)
235  {
236  for(int i = 0; i < class_number; i++)
237  P[i] = P[i] * probability_sum;
238  }
239  else
240  {
241  for(int i = 0; i < class_number; i++)
242  P[i] = (weights[i] > 0) ? probability_sum * P[i] / weights[i] : 0.f;
243  }
244  }
245  else
246  for(int i = 0; i < children_number; i++)
248 }
249 
251 {
252  if (is_leaf())
253  P[class_index] = 0;
254  else
255  for(int i = 0; i < children_number; i++)
257 }
258 
260 {
261  if (is_leaf())
262  wfs << probability_sum << " ";
263  else
264  for(int i = 0; i < children_number; i++)
266 }
267 
269 {
270  if (is_leaf())
271  wfs >> probability_sum;
272  else
273  for(int i = 0; i < children_number; i++)
275 }
276 
278 {
279  if (is_leaf())
280  return 1;
281  else
282  {
283  int n = 0;
284 
285  for(int i = 0; i < children_number; i++)
286  n += children[i]->leaves_number();
287 
288  return n;
289  }
290 }
291 
293 {
294  if (is_leaf())
295  return 0;
296  else
297  {
298  int n = 1;
299 
300  for(int i = 0; i < children_number; i++)
301  n += children[i]->node_number();
302 
303  return n;
304  }
305 }
306 
307 void image_classification_node::set_Dot(int image_width, int image_height)
308 {
309  int d;
310 
311  d = image_width / 2;
312 
313  du1 = int(d * rand_m1p1());
314  dv1 = int(d * rand_m1p1());
315 
316  du2 = int(d * rand_m1p1());
317  dv2 = int(d * rand_m1p1());
318 
319  int u0 = image_width / 2, v0 = image_height / 2;
320  d1 = (v0 + dv1) * image_width + u0 + du1;
321  d2 = (v0 + dv2) * image_width + u0 + du2;
322 
323  leaf = false;
324 }
325 
326 void image_classification_node::set_Dot(int _du1, int _dv1, int _du2, int _dv2, int image_width, int image_height)
327 {
328  du1 = _du1;
329  dv1 = _dv1;
330  du2 = _du2;
331  dv2 = _dv2;
332 
333  int u0 = image_width / 2, v0 = image_height / 2;
334  d1 = (v0 + dv1) * image_width + u0 + du1;
335  d2 = (v0 + dv2) * image_width + u0 + du2;
336 
337  leaf = false;
338 }
339 
340 ostream& operator<< (ostream& o, const image_classification_node& node)
341 {
342  int i;
343 
344  if (node.is_leaf())
345  {
346  o << "LEAF " << node.index << " " << node.depth << endl;
347  o << node.class_number << " classes" << endl;
348 
349  if (node.P != 0)
350  for(i = 0; i < node.class_number; i++)
351  if (node.P[i] > 0.001)
352  o << i << " " << node.P[i] << endl;
353 
354  o << "-1 -1" << endl;
355  }
356  else
357  {
358  o << "NODE " << node.index << " " << node.depth << endl;
359  o << "2dots_tau0" << endl; // Kept for compatibility with older versions
360  o << 0 << " " << node.du1 << " " << node.dv1 << " " << node.du2 << " " << node.dv2 << endl;
361  for(i = 0; i < node.children_number; i++)
362  o << node.children[i]->index << " ";
363  o << endl;
364  for(i = 0; i < node.children_number; i++)
365  o << *node.children[i];
366  }
367 
368  return o;
369 }
370 
373 
374 istream& operator>> (istream& is, image_classification_node& node)
375 {
376  char dummyString[1000];
377  char node_type[1000];
378 
379  is >> node_type;
380 
381  if (strcmp(node_type, "LEAF") == 0)
382  {
383  is >> node.index >> node.depth;
384  is >> node.class_number >> dummyString ;
385  node.P = new float[node.class_number];
386  node.best_class = 0;
387  float best_p = 0;
388  for(int i = 0; i < node.class_number; i++)
389  node.P[i] = 0;
390 
391  int ci;
392  do
393  {
394  float p;
395  is >> ci >> p;
396  if (ci >= 0)
397  {
398  node.P[ci] = p;
399 
400  if (p > best_p)
401  {
402  best_p = p;
403  node.best_class = ci;
404  }
405  }
406  } while (ci >= 0);
407  }
408  else if (strcmp(node_type, "NODE") == 0)
409  {
410  int _scale, _du1, _dv1, _du2, _dv2;
411 
412  is >> node.index >> node.depth;
413 
414  is >> dummyString; // Always 2dots_tau0 : Kept for compatibily with older versions of garfield lib
415 
416  is >> _scale >> _du1 >> _dv1 >> _du2 >> _dv2;
417  node.set_Dot(_du1, _dv1, _du2, _dv2, global_patch_size, global_patch_size);
418 
419  node.children_index = new int[node.children_number];
420 
421  for(int i = 0; i < node.children_number; i++)
422  is >> node.children_index[i];
423  }
424  else
425  {
426  cerr << "Error while reading image_classification_node (token = " << node_type << ")." << endl;
427  //throw exception("Error while reading image_classification_node"); //TODO A FAIRE
428  }
429 
430  return is;
431 }
432