(no commit message)
[pom.git] / pom.cc
1
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.                                //
6 //                                                                              //
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.                                     //
11 //                                                                              //
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/>.         //
14 //                                                                              //
15 // Written by Francois Fleuret                                                  //
16 // (C) Ecole Polytechnique Federale de Lausanne                                 //
17 // Contact <pom@epfl.ch> for comments & bug reports                             //
18 //////////////////////////////////////////////////////////////////////////////////
19
20 #include <iostream>
21 #include <fstream>
22
23 using namespace std;
24
25 #include "misc.h"
26 #include "global.h"
27 #include "vector.h"
28 #include "room.h"
29 #include "pom_solver.h"
30
31 void check_parameter(char *s, int line_number, char *buffer) {
32   if(!s) {
33     cerr << "Missing parameter line " << line_number << ":" << endl;
34     cerr << buffer << endl;
35     exit(1);
36   }
37 }
38
39 int main(int argc, char **argv) {
40
41   if(argc > 2) {
42     cerr << argv[0] << " [-h | --help | <configuration file>]" << endl;
43     exit(1);
44   }
45
46   ifstream *configuration_file = 0;
47   istream *input_stream;
48
49   if(argc > 1) {
50     if(strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
51       cout << argv[0] << " [-h | --help | <configuration file>]" << endl
52            << endl
53            << "  If a configuration file name is provided, the program processes it" << endl
54            << "  and prints information about the files it generates. Otherwise, it" << endl
55            << "  reads the standard input and does not produce any printout on the" <<
56            << "  standard output unless an error occurs." << endl
57            << endl;
58       exit(0);
59     }
60     configuration_file = new ifstream(argv[1]);
61     if(configuration_file->fail()) {
62       cerr << "Can not open " << argv[1] << " for reading." << endl;
63       exit(1);
64     }
65     input_stream = configuration_file;
66   } else input_stream = &cin;
67
68   char input_view_format[buffer_size] = "";
69   char result_format[buffer_size] = "";
70   char result_view_format[buffer_size] = "";
71   char convergence_view_format[buffer_size] = "";
72
73   char buffer[buffer_size], token[buffer_size];
74
75   int line_number = 0;
76   Vector<ProbaView *> *proba_views = 0;
77
78   Room *room = 0;
79
80   while(!input_stream->eof()) {
81
82     input_stream->getline(buffer, buffer_size);
83     line_number++;
84
85     char *s = buffer;
86     s = next_word(token, s, buffer_size);
87
88     if(strcmp(token, "ROOM") == 0) {
89       int view_width = -1, view_height = -1;
90       int nb_positions = -1;
91       int nb_cameras = -1;
92
93       check_parameter(s, line_number, buffer);
94       s = next_word(token, s, buffer_size);
95       view_width = atoi(token);
96
97       check_parameter(s, line_number, buffer);
98       s = next_word(token, s, buffer_size);
99       view_height = atoi(token);
100
101       check_parameter(s, line_number, buffer);
102       s = next_word(token, s, buffer_size);
103       nb_cameras = atoi(token);
104
105       check_parameter(s, line_number, buffer);
106       s = next_word(token, s, buffer_size);
107       nb_positions = atoi(token);
108
109       if(room) {
110         cerr << "Room already defined, line" << line_number << "." << endl;
111         exit(1);
112       }
113
114       room = new Room(view_width, view_height, nb_cameras, nb_positions);
115       proba_views = new Vector<ProbaView *>(nb_cameras);
116       for(int c = 0; c < proba_views->length(); c++)
117         (*proba_views)[c] = new ProbaView(view_width, view_height);
118     }
119
120     else if(strcmp(token, "CONVERGENCE_VIEW_FORMAT") == 0) {
121       check_parameter(s, line_number, buffer);
122       s = next_word(convergence_view_format, s, buffer_size);
123     }
124
125     else if(strcmp(token, "INPUT_VIEW_FORMAT") == 0) {
126       check_parameter(s, line_number, buffer);
127       s = next_word(input_view_format, s, buffer_size);
128     }
129
130     else if(strcmp(token, "RESULT_VIEW_FORMAT") == 0) {
131       check_parameter(s, line_number, buffer);
132       s = next_word(result_view_format, s, buffer_size);
133     }
134
135     else if(strcmp(token, "RESULT_FORMAT") == 0) {
136       check_parameter(s, line_number, buffer);
137       s = next_word(result_format, s, buffer_size);
138     }
139
140     else if(strcmp(token, "PROCESS") == 0) {
141       RGBImage tmp;
142       int first_frame, nb_frames;
143
144       check_parameter(s, line_number, buffer);
145       s = next_word(token, s, buffer_size);
146       first_frame = atoi(token);
147
148       check_parameter(s, line_number, buffer);
149       s = next_word(token, s, buffer_size);
150       nb_frames = atoi(token);
151
152       POMSolver solver(room);
153
154       Vector<scalar_t> prior(room->nb_positions());
155       Vector<scalar_t> proba_presence(room->nb_positions());
156       for(int i = 0; i < room->nb_positions(); i++) prior[i] = global_prior;
157
158       if(strcmp(input_view_format, "") == 0) {
159         cerr << "You must specify the input view format." << endl;
160         exit(1);
161       }
162
163       for(int f = first_frame; f < first_frame + nb_frames; f++) {
164
165         if(configuration_file)
166           cout << "Processing frame " << f << endl;
167
168         for(int c = 0; c < room->nb_cameras(); c++) {
169           pomsprintf(buffer, buffer_size, input_view_format, c, f, 0);
170           tmp.read_png(buffer);
171           (*proba_views)[c]->from_image(&tmp);
172         }
173
174         if(strcmp(convergence_view_format, "") != 0)
175           solver.solve(room, &prior, proba_views, &proba_presence, f, convergence_view_format);
176         else
177           solver.solve(room, &prior, proba_views, &proba_presence, f, 0);
178
179         if(strcmp(result_view_format, "") != 0)
180           for(int c = 0; c < room->nb_cameras(); c++) {
181             pomsprintf(buffer, buffer_size, result_view_format, c, f, 0);
182             if(configuration_file)
183               cout << "Saving " << buffer << endl;
184             room->save_stochastic_view(buffer, c, (*proba_views)[c], &proba_presence);
185           }
186
187         if(strcmp(result_format, "") != 0) {
188           pomsprintf(buffer, buffer_size, result_format, 0, f, 0);
189           ofstream result(buffer);
190           if(result.fail()) {
191             cerr << "Can not open " << token << " for writing." << endl;
192             exit(1);
193           }
194           if(configuration_file)
195             cout << "Saving " << buffer << endl;
196           for(int i = 0; i < room->nb_positions(); i++)
197             result << i << " " << proba_presence[i] << endl;
198           result.flush();
199         }
200       }
201     }
202
203     else if(strcmp(token, "RECTANGLE") == 0) {
204       int n_camera, n_position;
205
206       if(!room) {
207         cerr << "You must define a room before adding rectangles, line" << line_number << "." << endl;
208         exit(1);
209       }
210
211       check_parameter(s, line_number, buffer);
212       s = next_word(token, s, buffer_size);
213       n_camera = atoi(token);
214
215       if(n_camera < 0 || n_camera >= room->nb_cameras()) {
216         cerr << "Out of range camera number line " << line_number << "." << endl;
217         exit(1);
218       }
219
220       check_parameter(s, line_number, buffer);
221       s = next_word(token, s, buffer_size);
222       n_position = atoi(token);
223
224       if(n_position < 0 || n_camera >= room->nb_positions()) {
225         cerr << "Out of range position number line " << line_number << "." << endl;
226         exit(1);
227       }
228
229       Rectangle *current = room->avatar(n_camera, n_position);
230
231       check_parameter(s, line_number, buffer);
232       s = next_word(token, s, buffer_size);
233       if(strcmp(token, "notvisible") == 0) {
234         current->visible = false;
235         current->xmin = -1;
236         current->ymin = -1;
237         current->xmax = -1;
238         current->ymax = -1;
239       } else {
240         current->visible = true;
241         current->xmin = atoi(token);
242         check_parameter(s, line_number, buffer);
243         s = next_word(token, s, buffer_size);
244         current->ymin = atoi(token);
245         check_parameter(s, line_number, buffer);
246         s = next_word(token, s, buffer_size);
247         current->xmax = atoi(token);
248         check_parameter(s, line_number, buffer);
249         s = next_word(token, s, buffer_size);
250         current->ymax = atoi(token);
251
252         if(current->xmin < 0 || current->xmax >= room->view_width() ||
253            current->ymin < 0 || current->ymax >= room->view_height()) {
254           cerr << "Rectangle out of bounds, line " << line_number << endl;
255           exit(1);
256         }
257       }
258     }
259
260     else if(strcmp(token, "PRIOR") == 0) {
261       check_parameter(s, line_number, buffer);
262       s = next_word(token, s, buffer_size);
263       global_prior = atof(token);
264     }
265
266     else if(strcmp(token, "SIGMA_IMAGE_DENSITY") == 0) {
267       check_parameter(s, line_number, buffer);
268       s = next_word(token, s, buffer_size);
269       global_sigma_image_density = atof(token);
270     }
271
272     else if(strcmp(token, "SMOOTHING_COEFFICIENT") == 0) {
273       check_parameter(s, line_number, buffer);
274       s = next_word(token, s, buffer_size);
275       global_smoothing_coefficient = atof(token);
276     }
277
278     else if(strcmp(token, "MAX_NB_SOLVER_ITERATIONS") == 0) {
279       check_parameter(s, line_number, buffer);
280       s = next_word(token, s, buffer_size);
281       global_max_nb_solver_iterations = atoi(token);
282     }
283
284     else if(strcmp(token, "ERROR_MAX") == 0) {
285       check_parameter(s, line_number, buffer);
286       s = next_word(token, s, buffer_size);
287       global_error_max = atof(token);
288     }
289
290     else if(strcmp(token, "NB_STABLE_ERROR_FOR_CONVERGENCE") == 0) {
291       check_parameter(s, line_number, buffer);
292       s = next_word(token, s, buffer_size);
293       global_nb_stable_error_for_convergence = atoi(token);
294     }
295
296     else if(strcmp(token, "PROBA_IGNORED") == 0) {
297       check_parameter(s, line_number, buffer);
298       s = next_word(token, s, buffer_size);
299       global_proba_ignored = atof(token);
300     }
301
302     else if(strcmp(buffer, "") == 0 || buffer[0] == '#') { }
303
304     else {
305       cerr << "Unknown token " << token << ".";
306       exit(1);
307     }
308   }
309
310   if(proba_views)
311     for(int c = 0; c < proba_views->length(); c++) delete (*proba_views)[c];
312
313   delete proba_views;
314   delete room;
315
316   delete configuration_file;
317 }