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 version 3 as
13 * published by the Free Software Foundation.
15 * folded-ctf is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with folded-ctf. If not, see <http://www.gnu.org/licenses/>.
31 #include "param_parser.h"
32 #include "labelled_image.h"
34 void parse_warning(const char *message, char *file, int line) {
35 cerr << message << " " << file << ":" << line << "." << endl;
39 void parse_error(const char *message, char *file, int line) {
40 cerr << message << " " << file << ":" << line << "." << endl;
45 //////////////////////////////////////////////////////////////////////
47 void list_to_pool(char *main_path, char *list_name, char *pool_name) {
48 ifstream list_stream(list_name);
50 if(list_stream.fail()) {
51 cerr << "Can not open " << list_name << " for reading." << endl;
55 ofstream pool_stream(pool_name);
57 if(pool_stream.fail()) {
58 cerr << "Can not open " << pool_name << " for writing." << endl;
66 LabelledImage *current_image = 0;
67 bool open_current_cat = false;
68 bool head_defined = false;
69 bool bounding_box_defined = false;
70 bool belly_defined = false;
73 while(!list_stream.eof() && (global.nb_images < 0 || nb_scenes < global.nb_images)) {
74 char line[large_buffer_size], token[buffer_size], full_image_name[buffer_size];
75 list_stream.getline(line, large_buffer_size);
78 s = next_word(token, s, buffer_size);
80 //////////////////////////////////////////////////////////////////////
82 if(strcmp(token, "SCENE") == 0) {
85 parse_error("Non-closed scene ", list_name, line_number);
89 s = next_word(token, s, buffer_size);
90 sprintf(full_image_name, "%s/%s", main_path, token);
92 parse_error("Image name is missing ", list_name, line_number);
95 cout << "Processing scene " << full_image_name << "." << endl;
97 int nb_cats_in_current_image = -1;
100 s = next_word(token, s, buffer_size);
101 nb_cats_in_current_image = atoi(token);
103 parse_error("Number of cats is missing ", list_name, line_number);
106 if(nb_cats_in_current_image < 0 || nb_cats_in_current_image > 100) {
107 parse_error("Weird number of cats ", list_name, line_number);
111 tmp.read_jpg(full_image_name);
113 current_image = new LabelledImage(tmp.width(),
115 nb_cats_in_current_image);
117 for(int y = 0; y < tmp.height(); y++) {
118 for(int x = 0; x < tmp.width(); x++) {
119 current_image->set_value(x, y,
120 int(scalar_t(tmp.pixel(x, y, 0)) * 0.2989 +
121 scalar_t(tmp.pixel(x, y, 1)) * 0.5870 +
122 scalar_t(tmp.pixel(x, y, 2)) * 0.1140));
129 else if(strcmp(token, "END_SCENE") == 0) {
130 if(current_image == 0)
131 parse_error("Non-open scene ", list_name, line_number);
133 if(nb_cats < current_image->nb_targets()) {
134 parse_warning("Less cats than advertised (some were ignored?), scene ignored",
135 list_name, line_number);
137 current_image->write(&pool_stream);
141 delete current_image;
145 //////////////////////////////////////////////////////////////////////
147 else if(strcmp(token, "CAT") == 0) {
149 parse_error("Non-closed cat ", list_name, line_number);
150 if(current_image == 0)
151 parse_error("Cat without scene ", list_name, line_number);
152 if(nb_cats >= current_image->nb_targets())
153 parse_error("More cats than advertised", list_name, line_number);
154 open_current_cat = true;
155 head_defined = false;
156 bounding_box_defined = false;
157 belly_defined = false;
161 else if(strcmp(token, "END_CAT") == 0) {
162 if(!open_current_cat)
163 parse_error("Undefined cat ", list_name, line_number);
165 if(!bounding_box_defined) {
166 parse_error("Undefined bounding box ", list_name, line_number);
169 if(head_defined && belly_defined) {
170 if(current_image->get_target_pose(nb_cats)->_head_radius > global.min_head_radius &&
171 current_image->get_target_pose(nb_cats)->_head_radius < global.max_head_radius) {
174 cerr << "Cat ignored since the head radius ("
175 << current_image->get_target_pose(nb_cats)->_head_radius << ") is not in the tolerance ("
176 << global.min_head_radius << ", " << global.max_head_radius
178 << list_name << ":" << line_number
183 parse_warning("Cat ignored since either the head and/or the belly are undefined",
184 list_name, line_number);
187 open_current_cat = false;
190 //////////////////////////////////////////////////////////////////////
192 else if(strcmp(token, "BOUNDINGBOX") == 0) {
193 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
194 if(bounding_box_defined) parse_error("Two bounding box", list_name, line_number);
195 int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
196 if(s) { s = next_word(token, s, buffer_size); xmin = atoi(token); }
197 else parse_error("BOUNDINGBOX parameter xmin missing ", list_name, line_number);
198 if(s) { s = next_word(token, s, buffer_size); ymin = atoi(token); }
199 else parse_error("BOUNDINGBOX parameter ymin missing ", list_name, line_number);
200 if(s) { s = next_word(token, s, buffer_size); xmax = atoi(token); }
201 else parse_error("BOUNDINGBOX parameter xmax missing ", list_name, line_number);
202 if(s) { s = next_word(token, s, buffer_size); ymax = atoi(token); }
203 else parse_error("BOUNDINGBOX parameter ymax missing ", list_name, line_number);
204 current_image->get_target_pose(nb_cats)->_bounding_box_xmin = xmin;
205 current_image->get_target_pose(nb_cats)->_bounding_box_ymin = ymin;
206 current_image->get_target_pose(nb_cats)->_bounding_box_xmax = xmax;
207 current_image->get_target_pose(nb_cats)->_bounding_box_ymax = ymax;
208 bounding_box_defined = true;
211 //////////////////////////////////////////////////////////////////////
213 else if(strcmp(token, "HEADELLIPSE") == 0) {
214 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
215 if(head_defined) parse_error("Two head definitions", list_name, line_number);
216 int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
217 if(s) { s = next_word(token, s, buffer_size); xmin = atoi(token); }
218 else parse_error("HEADELLIPSE parameter xmin missing ", list_name, line_number);
219 if(s) { s = next_word(token, s, buffer_size); ymin = atoi(token); }
220 else parse_error("HEADELLIPSE parameter ymin missing ", list_name, line_number);
221 if(s) { s = next_word(token, s, buffer_size); xmax = atoi(token); }
222 else parse_error("HEADELLIPSE parameter xmax missing ", list_name, line_number);
223 if(s) { s = next_word(token, s, buffer_size); ymax = atoi(token); }
224 else parse_error("HEADELLIPSE parameter ymax missing ", list_name, line_number);
225 current_image->get_target_pose(nb_cats)->_head_xc = (xmin + xmax)/2;
226 current_image->get_target_pose(nb_cats)->_head_yc = (ymin + ymax)/2;
227 current_image->get_target_pose(nb_cats)->_head_radius = int(sqrt(scalar_t(xmax - xmin) * scalar_t(ymax - ymin))/2);
231 else if(strcmp(token, "BELLYLOCATION") == 0) {
232 if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
233 int x1 = -1, y1 = -1;
235 if(s) { s = next_word(token, s, buffer_size); x1 = atoi(token); }
236 else parse_error("BELLYLOCATION parameter x1 missing ", list_name, line_number);
237 if(s) { s = next_word(token, s, buffer_size); y1 = atoi(token); }
238 else parse_error("BELLYLOCATION parameter y1 missing ", list_name, line_number);
241 parse_error("More than one belly location. ", list_name, line_number);
244 Pose *pose = current_image->get_target_pose(nb_cats);
246 pose->_belly_xc = x1;
247 pose->_belly_yc = y1;
249 belly_defined = true;
255 //////////////////////////////////////////////////////////////////////
257 int main(int argc, char **argv) {
258 char *new_argv[argc];
263 global.init_parser(&parser);
264 parser.parse_options(argc, argv, false, &new_argc, new_argv);
265 global.read_parser(&parser);
266 cout << "-- PARAMETERS --------------------------------------------------------" << endl;
267 parser.print_all(&cout);
271 cerr << new_argv[0] << " <list file> <image path> <pool name>" << endl;
275 cout << "From list " << new_argv[1]
276 << " and image dir " << new_argv[2]
277 << ", generating pool " << new_argv[3]
280 cout << "-- GENERATING IMAGES -------------------------------------------------" << endl;
282 list_to_pool(new_argv[2], new_argv[1], new_argv[3]);
284 cout << "-- FINISHED ----------------------------------------------------------" << endl;