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 ///////////////////////////////////////////////////////////////////////////
25 #include "param_parser.h"
26 #include "labelled_image.h"
28 void parse_warning(const char *message, char *file, int line) {
29 cerr << message << " " << file << ":" << line << "." << endl;
33 void parse_error(const char *message, char *file, int line) {
34 cerr << message << " " << file << ":" << line << "." << endl;
39 //////////////////////////////////////////////////////////////////////
41 void list_to_pool(char *main_path, char *list_name, char *pool_name) {
42 ifstream list_stream(list_name);
44 if(list_stream.fail()) {
45 cerr << "Can not open " << list_name << " for reading." << endl;
49 ofstream pool_stream(pool_name);
51 if(pool_stream.fail()) {
52 cerr << "Can not open " << pool_name << " for writing." << endl;
60 LabelledImage *current_image = 0;
61 bool open_current_cat = false;
62 bool head_defined = false;
63 bool bounding_box_defined = false;
64 bool belly_defined = false;
67 while(!list_stream.eof() && (global.nb_images < 0 || nb_scenes < global.nb_images)) {
68 char line[large_buffer_size], token[buffer_size], full_image_name[buffer_size];
69 list_stream.getline(line, large_buffer_size);
72 s = next_word(token, s, buffer_size);
74 //////////////////////////////////////////////////////////////////////
76 if(strcmp(token, "SCENE") == 0) {
79 parse_error("Non-closed scene ", list_name, line_number);
83 s = next_word(token, s, buffer_size);
84 sprintf(full_image_name, "%s/%s", main_path, token);
86 parse_error("Image name is missing ", list_name, line_number);
89 cout << "Processing scene " << full_image_name << "." << endl;
91 int nb_cats_in_current_image = -1;
94 s = next_word(token, s, buffer_size);
95 nb_cats_in_current_image = atoi(token);
97 parse_error("Number of cats is missing ", list_name, line_number);
100 if(nb_cats_in_current_image < 0 || nb_cats_in_current_image > 100) {
101 parse_error("Weird number of cats ", list_name, line_number);
105 tmp.read_jpg(full_image_name);
107 current_image = new LabelledImage(tmp.width(),
109 nb_cats_in_current_image);
111 for(int y = 0; y < tmp.height(); y++) {
112 for(int x = 0; x < tmp.width(); x++) {
113 current_image->set_value(x, y,
114 int(scalar_t(tmp.pixel(x, y, 0)) * 0.2989 +
115 scalar_t(tmp.pixel(x, y, 1)) * 0.5870 +
116 scalar_t(tmp.pixel(x, y, 2)) * 0.1140));
123 else if(strcmp(token, "END_SCENE") == 0) {
124 if(current_image == 0)
125 parse_error("Non-open scene ", list_name, line_number);
127 if(nb_cats < current_image->nb_targets()) {
128 parse_warning("Less cats than advertised (some were ignored?), scene ignored",
129 list_name, line_number);
131 current_image->write(&pool_stream);
135 delete current_image;
139 //////////////////////////////////////////////////////////////////////
141 else if(strcmp(token, "CAT") == 0) {
143 parse_error("Non-closed cat ", list_name, line_number);
144 if(current_image == 0)
145 parse_error("Cat without scene ", list_name, line_number);
146 if(nb_cats >= current_image->nb_targets())
147 parse_error("More cats than advertised", list_name, line_number);
148 open_current_cat = true;
149 head_defined = false;
150 bounding_box_defined = false;
151 belly_defined = false;
155 else if(strcmp(token, "END_CAT") == 0) {
156 if(!open_current_cat)
157 parse_error("Undefined cat ", list_name, line_number);
159 if(!bounding_box_defined) {
160 parse_error("Undefined bounding box ", list_name, line_number);
163 if(head_defined && belly_defined) {
164 if(current_image->get_target_pose(nb_cats)->_head_radius > global.min_head_radius &&
165 current_image->get_target_pose(nb_cats)->_head_radius < global.max_head_radius) {
168 cerr << "Cat ignored since the head radius ("
169 << current_image->get_target_pose(nb_cats)->_head_radius << ") is not in the tolerance ("
170 << global.min_head_radius << ", " << global.max_head_radius
172 << list_name << ":" << line_number
177 parse_warning("Cat ignored since either the head and/or the belly are undefined",
178 list_name, line_number);
181 open_current_cat = false;
184 //////////////////////////////////////////////////////////////////////
186 else if(strcmp(token, "BOUNDINGBOX") == 0) {
187 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
188 if(bounding_box_defined) parse_error("Two bounding box", list_name, line_number);
189 int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
190 if(s) { s = next_word(token, s, buffer_size); xmin = atoi(token); }
191 else parse_error("BOUNDINGBOX parameter xmin missing ", list_name, line_number);
192 if(s) { s = next_word(token, s, buffer_size); ymin = atoi(token); }
193 else parse_error("BOUNDINGBOX parameter ymin missing ", list_name, line_number);
194 if(s) { s = next_word(token, s, buffer_size); xmax = atoi(token); }
195 else parse_error("BOUNDINGBOX parameter xmax missing ", list_name, line_number);
196 if(s) { s = next_word(token, s, buffer_size); ymax = atoi(token); }
197 else parse_error("BOUNDINGBOX parameter ymax missing ", list_name, line_number);
198 current_image->get_target_pose(nb_cats)->_bounding_box_xmin = xmin;
199 current_image->get_target_pose(nb_cats)->_bounding_box_ymin = ymin;
200 current_image->get_target_pose(nb_cats)->_bounding_box_xmax = xmax;
201 current_image->get_target_pose(nb_cats)->_bounding_box_ymax = ymax;
202 bounding_box_defined = true;
205 //////////////////////////////////////////////////////////////////////
207 else if(strcmp(token, "HEADELLIPSE") == 0) {
208 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
209 if(head_defined) parse_error("Two head definitions", list_name, line_number);
210 int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
211 if(s) { s = next_word(token, s, buffer_size); xmin = atoi(token); }
212 else parse_error("HEADELLIPSE parameter xmin missing ", list_name, line_number);
213 if(s) { s = next_word(token, s, buffer_size); ymin = atoi(token); }
214 else parse_error("HEADELLIPSE parameter ymin missing ", list_name, line_number);
215 if(s) { s = next_word(token, s, buffer_size); xmax = atoi(token); }
216 else parse_error("HEADELLIPSE parameter xmax missing ", list_name, line_number);
217 if(s) { s = next_word(token, s, buffer_size); ymax = atoi(token); }
218 else parse_error("HEADELLIPSE parameter ymax missing ", list_name, line_number);
219 current_image->get_target_pose(nb_cats)->_head_xc = (xmin + xmax)/2;
220 current_image->get_target_pose(nb_cats)->_head_yc = (ymin + ymax)/2;
221 current_image->get_target_pose(nb_cats)->_head_radius = int(sqrt(scalar_t(xmax - xmin) * scalar_t(ymax - ymin))/2);
225 else if(strcmp(token, "BELLYLOCATION") == 0) {
226 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
227 int x1 = -1, y1 = -1;
229 if(s) { s = next_word(token, s, buffer_size); x1 = atoi(token); }
230 else parse_error("BELLYLOCATION parameter x1 missing ", list_name, line_number);
231 if(s) { s = next_word(token, s, buffer_size); y1 = atoi(token); }
232 else parse_error("BELLYLOCATION parameter y1 missing ", list_name, line_number);
235 parse_error("More than one belly location. ", list_name, line_number);
238 Pose *pose = current_image->get_target_pose(nb_cats);
240 pose->_belly_xc = x1;
241 pose->_belly_yc = y1;
243 belly_defined = true;
249 //////////////////////////////////////////////////////////////////////
251 int main(int argc, char **argv) {
252 char *new_argv[argc];
257 global.init_parser(&parser);
258 parser.parse_options(argc, argv, false, &new_argc, new_argv);
259 global.read_parser(&parser);
260 cout << "-- PARAMETERS --------------------------------------------------------" << endl;
261 parser.print_all(&cout);
265 cerr << new_argv[0] << " <list file> <image path> <pool name>" << endl;
269 cout << "From list " << new_argv[1]
270 << " and image dir " << new_argv[2]
271 << ", generating pool " << new_argv[3]
274 cout << "-- GENERATING IMAGES -------------------------------------------------" << endl;
276 list_to_pool(new_argv[2], new_argv[1], new_argv[3]);
278 cout << "-- FINISHED ----------------------------------------------------------" << endl;