2 * folded-ctf is an implementation of the folded hierarchy of
3 * classifiers for object detection, developed by Francois Fleuret
6 * Copyright (c) 2008 Idiap Research Institute, http://www.idiap.ch/
7 * Written by Francois Fleuret <francois.fleuret@idiap.ch>
9 * This file is part of folded-ctf.
11 * folded-ctf is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published
13 * by the Free Software Foundation, either version 3 of the License,
14 * or (at your option) any later version.
16 * folded-ctf is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with folded-ctf. If not, see <http://www.gnu.org/licenses/>.
32 #include "param_parser.h"
33 #include "labelled_image.h"
35 void parse_warning(const char *message, char *file, int line) {
36 cerr << message << " " << file << ":" << line << "." << endl;
40 void parse_error(const char *message, char *file, int line) {
41 cerr << message << " " << file << ":" << line << "." << endl;
46 //////////////////////////////////////////////////////////////////////
48 void list_to_pool(char *main_path, char *list_name, char *pool_name) {
49 ifstream list_stream(list_name);
51 if(list_stream.fail()) {
52 cerr << "Can not open " << list_name << " for reading." << endl;
56 ofstream pool_stream(pool_name);
58 if(pool_stream.fail()) {
59 cerr << "Can not open " << pool_name << " for writing." << endl;
67 LabelledImage *current_image = 0;
68 bool open_current_cat = false;
69 bool head_defined = false;
70 bool bounding_box_defined = false;
71 bool belly_defined = false;
74 while(!list_stream.eof() && (global.nb_images < 0 || nb_scenes < global.nb_images)) {
75 char line[large_buffer_size], token[buffer_size], full_image_name[buffer_size];
76 list_stream.getline(line, large_buffer_size);
79 s = next_word(token, s, buffer_size);
81 //////////////////////////////////////////////////////////////////////
83 if(strcmp(token, "SCENE") == 0) {
86 parse_error("Non-closed scene ", list_name, line_number);
90 s = next_word(token, s, buffer_size);
91 sprintf(full_image_name, "%s/%s", main_path, token);
93 parse_error("Image name is missing ", list_name, line_number);
96 cout << "Processing scene " << full_image_name << "." << endl;
98 int nb_cats_in_current_image = -1;
101 s = next_word(token, s, buffer_size);
102 nb_cats_in_current_image = atoi(token);
104 parse_error("Number of cats is missing ", list_name, line_number);
107 if(nb_cats_in_current_image < 0 || nb_cats_in_current_image > 100) {
108 parse_error("Weird number of cats ", list_name, line_number);
112 tmp.read_jpg(full_image_name);
114 current_image = new LabelledImage(tmp.width(),
116 nb_cats_in_current_image);
118 for(int y = 0; y < tmp.height(); y++) {
119 for(int x = 0; x < tmp.width(); x++) {
120 current_image->set_value(x, y,
121 int(scalar_t(tmp.pixel(x, y, 0)) * 0.2989 +
122 scalar_t(tmp.pixel(x, y, 1)) * 0.5870 +
123 scalar_t(tmp.pixel(x, y, 2)) * 0.1140));
130 else if(strcmp(token, "END_SCENE") == 0) {
131 if(current_image == 0)
132 parse_error("Non-open scene ", list_name, line_number);
134 if(nb_cats < current_image->nb_targets()) {
135 parse_warning("Less cats than advertised (some were ignored?), scene ignored",
136 list_name, line_number);
138 current_image->write(&pool_stream);
142 delete current_image;
146 //////////////////////////////////////////////////////////////////////
148 else if(strcmp(token, "CAT") == 0) {
150 parse_error("Non-closed cat ", list_name, line_number);
151 if(current_image == 0)
152 parse_error("Cat without scene ", list_name, line_number);
153 if(nb_cats >= current_image->nb_targets())
154 parse_error("More cats than advertised", list_name, line_number);
155 open_current_cat = true;
156 head_defined = false;
157 bounding_box_defined = false;
158 belly_defined = false;
162 else if(strcmp(token, "END_CAT") == 0) {
163 if(!open_current_cat)
164 parse_error("Undefined cat ", list_name, line_number);
166 if(!bounding_box_defined) {
167 parse_error("Undefined bounding box ", list_name, line_number);
170 if(head_defined && belly_defined) {
171 if(current_image->get_target_pose(nb_cats)->_head_radius > global.min_head_radius &&
172 current_image->get_target_pose(nb_cats)->_head_radius < global.max_head_radius) {
175 cerr << "Cat ignored since the head radius ("
176 << current_image->get_target_pose(nb_cats)->_head_radius << ") is not in the tolerance ("
177 << global.min_head_radius << ", " << global.max_head_radius
179 << list_name << ":" << line_number
184 parse_warning("Cat ignored since either the head and/or the belly are undefined",
185 list_name, line_number);
188 open_current_cat = false;
191 //////////////////////////////////////////////////////////////////////
193 else if(strcmp(token, "BOUNDINGBOX") == 0) {
194 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
195 if(bounding_box_defined) parse_error("Two bounding box", list_name, line_number);
196 int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
197 if(s) { s = next_word(token, s, buffer_size); xmin = atoi(token); }
198 else parse_error("BOUNDINGBOX parameter xmin missing ", list_name, line_number);
199 if(s) { s = next_word(token, s, buffer_size); ymin = atoi(token); }
200 else parse_error("BOUNDINGBOX parameter ymin missing ", list_name, line_number);
201 if(s) { s = next_word(token, s, buffer_size); xmax = atoi(token); }
202 else parse_error("BOUNDINGBOX parameter xmax missing ", list_name, line_number);
203 if(s) { s = next_word(token, s, buffer_size); ymax = atoi(token); }
204 else parse_error("BOUNDINGBOX parameter ymax missing ", list_name, line_number);
205 current_image->get_target_pose(nb_cats)->_bounding_box_xmin = xmin;
206 current_image->get_target_pose(nb_cats)->_bounding_box_ymin = ymin;
207 current_image->get_target_pose(nb_cats)->_bounding_box_xmax = xmax;
208 current_image->get_target_pose(nb_cats)->_bounding_box_ymax = ymax;
209 bounding_box_defined = true;
212 //////////////////////////////////////////////////////////////////////
214 else if(strcmp(token, "HEADELLIPSE") == 0) {
215 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
216 if(head_defined) parse_error("Two head definitions", list_name, line_number);
217 int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
218 if(s) { s = next_word(token, s, buffer_size); xmin = atoi(token); }
219 else parse_error("HEADELLIPSE parameter xmin missing ", list_name, line_number);
220 if(s) { s = next_word(token, s, buffer_size); ymin = atoi(token); }
221 else parse_error("HEADELLIPSE parameter ymin missing ", list_name, line_number);
222 if(s) { s = next_word(token, s, buffer_size); xmax = atoi(token); }
223 else parse_error("HEADELLIPSE parameter xmax missing ", list_name, line_number);
224 if(s) { s = next_word(token, s, buffer_size); ymax = atoi(token); }
225 else parse_error("HEADELLIPSE parameter ymax missing ", list_name, line_number);
226 current_image->get_target_pose(nb_cats)->_head_xc = (xmin + xmax)/2;
227 current_image->get_target_pose(nb_cats)->_head_yc = (ymin + ymax)/2;
228 current_image->get_target_pose(nb_cats)->_head_radius = int(sqrt(scalar_t(xmax - xmin) * scalar_t(ymax - ymin))/2);
232 else if(strcmp(token, "BELLYLOCATION") == 0) {
233 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
234 int x1 = -1, y1 = -1;
236 if(s) { s = next_word(token, s, buffer_size); x1 = atoi(token); }
237 else parse_error("BELLYLOCATION parameter x1 missing ", list_name, line_number);
238 if(s) { s = next_word(token, s, buffer_size); y1 = atoi(token); }
239 else parse_error("BELLYLOCATION parameter y1 missing ", list_name, line_number);
242 parse_error("More than one belly location. ", list_name, line_number);
245 Pose *pose = current_image->get_target_pose(nb_cats);
247 pose->_belly_xc = x1;
248 pose->_belly_yc = y1;
250 belly_defined = true;
256 //////////////////////////////////////////////////////////////////////
258 int main(int argc, char **argv) {
259 char *new_argv[argc];
264 global.init_parser(&parser);
265 parser.parse_options(argc, argv, false, &new_argc, new_argv);
266 global.read_parser(&parser);
267 cout << "-- PARAMETERS --------------------------------------------------------" << endl;
268 parser.print_all(&cout);
272 cerr << new_argv[0] << " <list file> <image path> <pool name>" << endl;
276 cout << "From list " << new_argv[1]
277 << " and image dir " << new_argv[2]
278 << ", generating pool " << new_argv[3]
281 cout << "-- GENERATING IMAGES -------------------------------------------------" << endl;
283 list_to_pool(new_argv[2], new_argv[1], new_argv[3]);
285 cout << "-- FINISHED ----------------------------------------------------------" << endl;