bazar  1.3.1
image_classification_tree.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 #include <fstream>
23 #include <iostream>
24 #include <iomanip>
25 using namespace std;
26 
28 
29 #ifdef WIN32
30 #else
31 #include <sys/time.h>
32 #include <sys/resource.h>
33 #include <unistd.h>
34 #endif
35 
37 int used_memory() {
38 #ifdef WIN32
39  return 42;
40 #else
41  FILE *f;
42  int mem;
43  char fn[512];
44  sprintf(fn, "/proc/%d/statm", getpid());
45  f = fopen(fn, "r");
46  fscanf(f, "%d", &mem);
47  fclose(f);
48  return (mem*4)/1024;
49 #endif
50 }
51 
53  : image_classifier(_LearnProgress)
54 {
55  root = 0;
56 }
57 
58 
59 image_classification_tree::image_classification_tree(int _image_width, int _image_height,
60  int _class_number, int _max_depth,
61  LEARNPROGRESSION _LearnProgress)
62  : image_classifier(_image_width, _image_height, _class_number,_LearnProgress)
63 {
64  max_depth = _max_depth;
65 
66  root = 0;
67 }
68 
69 bool image_classification_tree::load(string filename)
70 {
71  string dummyString;
72 
73  try {
74  ifstream ifs(filename.data());
75 
76  ifs >> dummyString >> image_width >> image_height;
78  cout << "[Patch size: " << global_patch_size << "]" << flush;
79 
80  ifs >> dummyString >> class_number;
81  ifs >> dummyString >> max_depth;
82 
83  // Read nodes in an iterative way (faster than in a recursive way):
84  int nodes_plus_leaves_number;
85  ifs >> nodes_plus_leaves_number;
86 
87  image_classification_node ** nodes = new image_classification_node* [nodes_plus_leaves_number];
88 
89  try
90  {
91  for(int i = 0; i < nodes_plus_leaves_number; i++)
92  {
94  ifs >> *tmp_node;
95  nodes[tmp_node->index] = tmp_node;
96  }
97  }
98  catch (exception)
99  {
100  delete [] nodes;
101  return false;
102  }
103 
104  // Rebuild the tree:
105  root = nodes[0];
106  for(int i = 0; i < nodes_plus_leaves_number; i++)
107  {
108  image_classification_node * node = nodes[i];
109 
110  if ( !node->is_leaf() )
111  {
112  assert(node->children_number <= 3);
113 
114  for(int i = 0; i < node->children_number; i++)
115  {
116  node->children[i] = nodes[node->children_index[i]];
117  node->children[i]->parent = node;
118  }
119  delete [] node->children_index;
120  }
121  }
122 
123  delete [] nodes;
124 
125  }
126  catch (exception)
127  {
128  return false;
129  }
130 
131  cout << ". Ok." << endl;
132 
133  return true;
134 }
135 
137 {
138  if (root != 0)
139  delete root;
140 }
141 
142 bool image_classification_tree::save(string filename)
143 {
144  cout << "Saving tree (" << filename << ")..." << flush;
145 
146  ofstream ofs(filename.data());
147 
148  ofs << "image_size: " << image_width << " " << image_height << endl;
149  ofs << "class_number: " << class_number << endl;
150  ofs << "max_depth: " << max_depth << endl;
151 
152  ofs << node_number() + leaves_number() << endl;
153 
154  ofs << *root;
155 
156  ofs.close();
157 
158  cout << "...ok." << endl;
159 
160  return true;
161 }
162 
164 {
165  for(int i = 0; i < call_number; i++)
166  {
167  cout << "REFINEMENT: " << call_number - i << "... \r" << flush;
168 
169  vector<image_class_example *> * examples = vg->generate_random_examples();
170 
171  for(vector<image_class_example *>::iterator it = examples->begin(); it < examples->end(); it++)
172  {
174 
175  while(!node->is_leaf())
176  node = node->children[node->child_index(*it)];
177 
178  node->P[(*it)->class_index]++;
179  }
180 
181  delete examples;
182 
183  vg->release_examples();
184  }
185 
187 
188  cout << "Refinement done (" << call_number << " calls to generate_random_examples). " << endl;
189 }
190 
192 {
193  int * inlier_total = new int[class_number];
194  int * total = new int[class_number];
195 
196  for(int i = 0; i < class_number; i++)
197  inlier_total[i] = total[i] = 0;
198 
199  for(int i = 0; i < call_number; i++)
200  {
201  cout << "GENERATING TESTING SET: " << call_number - i << "... " << (char)13 << flush;
202 
203  vector<image_class_example *> * examples = vg->generate_random_examples();
204 
205  for(vector<image_class_example *>::iterator it = examples->begin(); it < examples->end(); it++)
206  {
207  int found_class_index = recognize(*it, 0);
208 
209  total[(*it)->class_index]++;
210  if ((*it)->class_index == found_class_index)
211  inlier_total[found_class_index]++;
212  }
213 
214  delete examples;
215 
216  vg->release_examples();
217  }
218 
219  cout << "Test: " << flush;
220  for(int i = 0; i < class_number; i++)
221  {
222  cout << "[class " << i << ": ";
223  if (total[i] == 0)
224  cout << "not represented !!!]." << flush;
225  else
226  cout << std::setprecision(1) << 100. * float(inlier_total[i]) / total[i] << "% inliers]." << flush;
227  }
228 
229  int T = 0, IT = 0;
230  for(int i = 0; i < class_number; i++)
231  {
232  T += total[i];
233  IT += inlier_total[i];
234  }
235 
236  cout << "ok) -> " << setprecision(1) << 100. * float(IT) / T << "% inliers." << endl;
237 }
238 
239 
240 int image_classification_tree::recognize(image_class_example * image, float * confidence, int /*dummy*/)
241 {
243 
244  while(!node->is_leaf())
245  node = node->children[node->child_index(image)];
246 
247  if (confidence != 0)
248  *confidence = node->P[node->best_class];
249 
250  return node->best_class;
251 }
252 
254 {
256  unsigned char * I = (unsigned char *)(pv->preprocessed->imageData);
257 
258  while(!node->is_leaf())
259  {
260  int dot_product = (int)I[node->d1] - (int)I[node->d2];
261 
262  if (dot_product <= 0)
263  node = node->children[0];
264  else
265  node = node->children[1];
266  }
267  return node->P;
268 }
269 
271 {
272  return root->node_number();
273 }
274 
276 {
277  return root->leaves_number();
278 }
279 
281 {
282  return 0;
283 }
284 
286 {
287  return 0.;
288 }
289 
290 image_classification_node * image_classification_tree::extract_node(vector <image_classification_node*> * L)
291 {
293  L->pop_back();
294 
295  return result;
296 }
297 
299 {
301 }
302