2 ///////////////////////////////////////////////////////////////////////////
3 // This program is free software: you can redistribute it and/or modify //
4 // it under the terms of the version 3 of the GNU General Public License //
5 // as published by the Free Software Foundation. //
7 // This program is distributed in the hope that it will be useful, but //
8 // WITHOUT ANY WARRANTY; without even the implied warranty of //
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
10 // General Public License for more details. //
12 // You should have received a copy of the GNU General Public License //
13 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
15 // Written by Francois Fleuret, (C) IDIAP //
16 // Contact <francois.fleuret@idiap.ch> for comments & bug reports //
17 ///////////////////////////////////////////////////////////////////////////
29 #include "param_parser.h"
31 #include "labelled_image_pool_file.h"
32 #include "labelled_image_pool_subset.h"
35 #include "pose_cell_hierarchy.h"
36 #include "error_rates.h"
37 #include "materials.h"
39 //////////////////////////////////////////////////////////////////////
41 void check(bool condition, const char *message) {
43 cerr << message << endl;
48 //////////////////////////////////////////////////////////////////////
50 int main(int argc, char **argv) {
56 cout << "**********************************************************************" << endl;
57 cout << "** COMPILED IN DEBUG MODE **" << endl;
58 cout << "**********************************************************************" << endl;
62 cout << "-- ARGUMENTS ---------------------------------------------------------" << endl;
63 for(int i = 0; i < argc; i++)
64 cout << (i > 0 ? " " : "") << argv[i] << (i < argc - 1 ? " \\" : "")
69 global.init_parser(&parser);
70 parser.parse_options(argc, argv, false, &new_argc, new_argv);
71 global.read_parser(&parser);
73 << "-- PARAMETERS --------------------------------------------------------"
75 parser.print_all(global.log_stream);
78 nice(global.niceness);
80 (*global.log_stream) << "INFO RANDOM_SEED " << global.random_seed << endl;
81 srand48(global.random_seed);
83 LabelledImagePool *main_pool = 0;
84 LabelledImagePool *train_pool = 0, *validation_pool = 0, *hierarchy_pool = 0;
85 LabelledImagePool *test_pool = 0;
86 Detector *detector = 0;
89 char buffer[buffer_size];
90 gethostname(buffer, buffer_size);
91 (*global.log_stream) << "INFO HOSTNAME " << buffer << endl;
94 for(int c = 1; c < new_argc; c++) {
96 if(strcmp(new_argv[c], "open-pool") == 0) {
98 << "-- OPENING POOL ------------------------------------------------------"
101 check(!main_pool, "Pool already opened.");
102 check(global.pool_name[0], "No pool file.");
104 main_pool = new LabelledImagePoolFile(global.pool_name);
106 bool for_test[main_pool->nb_images()];
107 bool for_train[main_pool->nb_images()];
108 bool for_validation[main_pool->nb_images()];
109 bool for_hierarchy[main_pool->nb_images()];
111 for(int n = 0; n < main_pool->nb_images(); n++) {
113 for_train[n] = false;
114 for_validation[n] = false;
115 scalar_t r = drand48();
116 if(r < global.proportion_for_train)
118 else if(r < global.proportion_for_train + global.proportion_for_validation)
119 for_validation[n] = true;
120 else if(global.proportion_for_test < 0 ||
121 r < global.proportion_for_train +
122 global.proportion_for_validation +
123 global.proportion_for_test)
125 for_hierarchy[n] = for_train[n] || for_validation[n];
128 train_pool = new LabelledImagePoolSubset(main_pool, for_train);
129 validation_pool = new LabelledImagePoolSubset(main_pool, for_validation);
130 hierarchy_pool = new LabelledImagePoolSubset(main_pool, for_hierarchy);
132 if(global.test_pool_name[0]) {
133 test_pool = new LabelledImagePoolFile(global.test_pool_name);
135 test_pool = new LabelledImagePoolSubset(main_pool, for_test);
139 << train_pool->nb_images() << " images for train, "
140 << validation_pool->nb_images() << " images for validation, "
141 << hierarchy_pool->nb_images() << " images for the hierarchy and "
142 << test_pool->nb_images() << " images for test."
147 else if(strcmp(new_argv[c], "write-target-poses") == 0) {
148 check(main_pool, "No pool available.");
149 LabelledImage *image;
150 for(int p = 0; p < main_pool->nb_images(); p++) {
151 image = main_pool->grab_image(p);
152 for(int t = 0; t < image->nb_targets(); t++) {
153 cout << "IMAGE " << p << " TARGET " << t << endl;
154 image->get_target_pose(t)->print(&cout);
156 main_pool->release_image(p);
160 //////////////////////////////////////////////////////////////////////
162 else if(strcmp(new_argv[c], "train-detector") == 0) {
163 cout << "-- TRAIN DETECTOR ----------------------------------------------------" << endl;
164 check(train_pool, "No train pool available.");
165 check(validation_pool, "No validation pool available.");
166 check(hierarchy_pool, "No hierarchy pool available.");
167 check(!detector, "Existing detector, can not train another one.");
168 detector = new Detector();
169 detector->train(train_pool, validation_pool, hierarchy_pool);
172 else if(strcmp(new_argv[c], "compute-thresholds") == 0) {
173 cout << "-- COMPUTE THRESHOLDS ------------------------------------------------" << endl;
174 check(validation_pool, "No validation pool available.");
175 check(detector, "No detector.");
176 detector->compute_thresholds(validation_pool, global.wanted_true_positive_rate);
179 else if(strcmp(new_argv[c], "check-hierarchy") == 0) {
180 cout << "-- CHECK HIERARCHY ---------------------------------------------------" << endl;
181 PoseCellHierarchy *h = new PoseCellHierarchy(hierarchy_pool);
182 cout << "Train incompatible poses " << h->nb_incompatible_poses(train_pool) << endl;
183 cout << "Validation incompatible poses " << h->nb_incompatible_poses(validation_pool) << endl;
187 //////////////////////////////////////////////////////////////////////
189 else if(strcmp(new_argv[c], "validate-detector") == 0) {
190 cout << "-- VALIDATE DETECTOR -------------------------------------------------" << endl;
192 check(validation_pool, "No validation pool available.");
193 check(detector, "No detector.");
195 print_decimated_error_rate(global.nb_levels - 1, validation_pool, detector);
198 //////////////////////////////////////////////////////////////////////
200 else if(strcmp(new_argv[c], "test-detector") == 0) {
201 cout << "-- TEST DETECTOR -----------------------------------------------------" << endl;
203 check(test_pool, "No test pool available.");
204 check(detector, "No detector.");
206 if(test_pool->nb_images() > 0) {
207 print_decimated_error_rate(global.nb_levels - 1, test_pool, detector);
209 cout << "No test image." << endl;
213 else if(strcmp(new_argv[c], "parse-images") == 0) {
214 cout << "-- PARSING IMAGES -----------------------------------------------------" << endl;
215 check(detector, "No detector.");
217 char image_name[buffer_size];
218 cin.getline(image_name, buffer_size);
219 if(strlen(image_name) > 0) {
220 parse_scene(detector, image_name);
225 //////////////////////////////////////////////////////////////////////
227 else if(strcmp(new_argv[c], "sequence-test-detector") == 0) {
228 cout << "-- SEQUENCE TEST DETECTOR --------------------------------------------" << endl;
230 check(test_pool, "No test pool available.");
231 check(detector, "No detector.");
233 if(test_pool->nb_images() > 0) {
235 for(int n = 0; n < global.nb_wanted_true_positive_rates; n++) {
236 scalar_t r = global.wanted_true_positive_rate *
237 scalar_t(n + 1) / scalar_t(global.nb_wanted_true_positive_rates);
238 cout << "Testint at tp " << r
239 << " (" << n + 1 << "/" << global.nb_wanted_true_positive_rates << ")"
241 (*global.log_stream) << "INFO THRESHOLD_FOR_TP " << r << endl;
242 detector->compute_thresholds(validation_pool, r);
243 print_decimated_error_rate(global.nb_levels - 1, test_pool, detector);
246 cout << "No test image." << endl;
250 //////////////////////////////////////////////////////////////////////
252 else if(strcmp(new_argv[c], "write-detector") == 0) {
253 cout << "-- WRITE DETECTOR ----------------------------------------------------" << endl;
254 ofstream out(global.detector_name);
256 cerr << "Can not write to " << global.detector_name << endl;
259 check(detector, "No detector available.");
260 detector->write(&out);
263 //////////////////////////////////////////////////////////////////////
265 else if(strcmp(new_argv[c], "read-detector") == 0) {
266 cout << "-- READ DETECTOR -----------------------------------------------------" << endl;
268 check(!detector, "Existing detector, can not load another one.");
270 ifstream in(global.detector_name);
272 cerr << "Can not read from " << global.detector_name << endl;
276 detector = new Detector();
280 //////////////////////////////////////////////////////////////////////
282 else if(strcmp(new_argv[c], "write-pool-images") == 0) {
283 cout << "-- WRITING POOL IMAGES -----------------------------------------------" << endl;
284 check(global.nb_images > 0, "You must set nb_images to a positive value.");
285 check(train_pool, "No train pool available.");
286 write_pool_images_with_poses_and_referentials(train_pool, detector);
289 else if(strcmp(new_argv[c], "produce-materials") == 0) {
290 cout << "-- PRODUCING MATERIALS -----------------------------------------------" << endl;
292 check(hierarchy_pool, "No hierarchy pool available.");
293 check(test_pool, "No test pool available.");
295 PoseCellHierarchy *hierarchy;
297 cout << "Creating hierarchy" << endl;
299 hierarchy = new PoseCellHierarchy(hierarchy_pool);
301 LabelledImage *image;
302 for(int p = 0; p < test_pool->nb_images(); p++) {
303 image = test_pool->grab_image(p);
304 if(image->width() == 640 && image->height() == 480) {
306 hierarchy->add_root_cells(image, &pcs);
307 cout << "WE HAVE " << pcs.nb_cells() << " CELLS" << endl;
309 test_pool->release_image(p);
317 //////////////////////////////////////////////////////////////////////
320 cerr << "Unknown action " << new_argv[c] << endl;
324 //////////////////////////////////////////////////////////////////////
331 delete validation_pool;
332 delete hierarchy_pool;
337 cout << "-- FINISHED ----------------------------------------------------------" << endl;