--- /dev/null
+
+///////////////////////////////////////////////////////////////////////////
+// This program is free software: you can redistribute it and/or modify //
+// it under the terms of the version 3 of the GNU General Public License //
+// as published by the Free Software Foundation. //
+// //
+// This program is distributed in the hope that it will be useful, but //
+// WITHOUT ANY WARRANTY; without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see <http://www.gnu.org/licenses/>. //
+// //
+// Written by Francois Fleuret, (C) IDIAP //
+// Contact <francois.fleuret@idiap.ch> for comments & bug reports //
+///////////////////////////////////////////////////////////////////////////
+
+#include <fstream>
+
+using namespace std;
+
+#include "misc.h"
+#include "global.h"
+#include "param_parser.h"
+#include "labelled_image.h"
+
+void parse_warning(const char *message, char *file, int line) {
+ cerr << message << " " << file << ":" << line << "." << endl;
+ cerr.flush();
+}
+
+void parse_error(const char *message, char *file, int line) {
+ cerr << message << " " << file << ":" << line << "." << endl;
+ cerr.flush();
+ exit(1);
+}
+
+//////////////////////////////////////////////////////////////////////
+
+void list_to_pool(char *main_path, char *list_name, char *pool_name) {
+ ifstream list_stream(list_name);
+
+ if(list_stream.fail()) {
+ cerr << "Can not open " << list_name << " for reading." << endl;
+ exit(1);
+ }
+
+ ofstream pool_stream(pool_name);
+
+ if(pool_stream.fail()) {
+ cerr << "Can not open " << pool_name << " for writing." << endl;
+ exit(1);
+ }
+
+ int line_number = 0;
+ int nb_scenes = 0;
+
+ int nb_cats = -1;
+ LabelledImage *current_image = 0;
+ bool open_current_cat = false;
+ bool head_defined = false;
+ bool bounding_box_defined = false;
+ bool body_defined = false;
+ int nb_ears = 0;
+
+ while(!list_stream.eof() && (global.nb_images < 0 || nb_scenes < global.nb_images)) {
+ char line[large_buffer_size], token[buffer_size], full_image_name[buffer_size];
+ list_stream.getline(line, large_buffer_size);
+ line_number++;
+ char *s = line;
+ s = next_word(token, s, buffer_size);
+
+ //////////////////////////////////////////////////////////////////////
+
+ if(strcmp(token, "SCENE") == 0) {
+
+ if(current_image) {
+ parse_error("Non-closed scene ", list_name, line_number);
+ }
+
+ if(s) {
+ s = next_word(token, s, buffer_size);
+ sprintf(full_image_name, "%s/%s", main_path, token);
+ } else {
+ parse_error("Image name is missing ", list_name, line_number);
+ }
+
+ cout << "Processing scene " << full_image_name << "." << endl;
+
+ int nb_cats_in_current_image = -1;
+
+ if(s) {
+ s = next_word(token, s, buffer_size);
+ nb_cats_in_current_image = atoi(token);
+ } else {
+ parse_error("Number of cats is missing ", list_name, line_number);
+ }
+
+ if(nb_cats_in_current_image < 0 || nb_cats_in_current_image > 100) {
+ parse_error("Weird number of cats ", list_name, line_number);
+ }
+
+ RGBImage tmp;
+ tmp.read_jpg(full_image_name);
+
+ current_image = new LabelledImage(tmp.width(),
+ tmp.height(),
+ nb_cats_in_current_image);
+
+ for(int y = 0; y < tmp.height(); y++) {
+ for(int x = 0; x < tmp.width(); x++) {
+ current_image->set_value(x, y,
+ int(scalar_t(tmp.pixel(x, y, 0)) * 0.2989 +
+ scalar_t(tmp.pixel(x, y, 1)) * 0.5870 +
+ scalar_t(tmp.pixel(x, y, 2)) * 0.1140));
+ }
+ }
+
+ nb_cats = 0;
+ }
+
+ else if(strcmp(token, "END_SCENE") == 0) {
+ if(current_image == 0)
+ parse_error("Non-open scene ", list_name, line_number);
+
+ if(nb_cats < current_image->nb_targets()) {
+ parse_warning("Less cats than advertised (some were ignored?), scene ignored",
+ list_name, line_number);
+ } else {
+ current_image->write(&pool_stream);
+ nb_scenes++;
+ }
+
+ delete current_image;
+ current_image = 0;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ else if(strcmp(token, "CAT") == 0) {
+ if(open_current_cat)
+ parse_error("Non-closed cat ", list_name, line_number);
+ if(current_image == 0)
+ parse_error("Cat without scene ", list_name, line_number);
+ if(nb_cats >= current_image->nb_targets())
+ parse_error("More cats than advertised", list_name, line_number);
+ open_current_cat = true;
+ head_defined = false;
+ bounding_box_defined = false;
+ body_defined = false;
+ nb_ears = 0;
+ }
+
+ else if(strcmp(token, "END_CAT") == 0) {
+ if(!open_current_cat)
+ parse_error("Undefined cat ", list_name, line_number);
+
+ if(!bounding_box_defined) {
+ parse_error("Undefined bounding box ", list_name, line_number);
+ }
+
+ if(head_defined && body_defined) {
+ if(current_image->get_target_pose(nb_cats)->_head_radius > global.min_head_radius &&
+ current_image->get_target_pose(nb_cats)->_head_radius < global.max_head_radius) {
+ nb_cats++;
+ } else {
+ cerr << "Cat ignored since the head radius ("
+ << current_image->get_target_pose(nb_cats)->_head_radius << ") is not in the tolerance ("
+ << global.min_head_radius << ", " << global.max_head_radius
+ << ") "
+ << list_name << ":" << line_number
+ << endl;
+ cerr.flush();
+ }
+ } else {
+ parse_warning("Cat ignored since either the body, head or belly are undefined",
+ list_name, line_number);
+ }
+
+ open_current_cat = false;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ else if(strcmp(token, "BODYBOX") == 0) {
+ if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
+ if(bounding_box_defined) parse_error("Two bounding box", list_name, line_number);
+ int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
+ if(s) { s = next_word(token, s, buffer_size); xmin = atoi(token); }
+ else parse_error("BODYBOX parameter xmin missing ", list_name, line_number);
+ if(s) { s = next_word(token, s, buffer_size); ymin = atoi(token); }
+ else parse_error("BODYBOX parameter ymin missing ", list_name, line_number);
+ if(s) { s = next_word(token, s, buffer_size); xmax = atoi(token); }
+ else parse_error("BODYBOX parameter xmax missing ", list_name, line_number);
+ if(s) { s = next_word(token, s, buffer_size); ymax = atoi(token); }
+ else parse_error("BODYBOX parameter ymax missing ", list_name, line_number);
+ current_image->get_target_pose(nb_cats)->_bounding_box_xmin = xmin;
+ current_image->get_target_pose(nb_cats)->_bounding_box_ymin = ymin;
+ current_image->get_target_pose(nb_cats)->_bounding_box_xmax = xmax;
+ current_image->get_target_pose(nb_cats)->_bounding_box_ymax = ymax;
+ bounding_box_defined = true;
+ }
+
+ //////////////////////////////////////////////////////////////////////
+
+ else if(strcmp(token, "HEADELLIPSE") == 0) {
+ if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
+ if(head_defined) parse_error("Two head definitions", list_name, line_number);
+ int xmin = -1, ymin = -1, xmax = -1, ymax = -1;
+ if(s) { s = next_word(token, s, buffer_size); xmin = atoi(token); }
+ else parse_error("HEADELLIPSE parameter xmin missing ", list_name, line_number);
+ if(s) { s = next_word(token, s, buffer_size); ymin = atoi(token); }
+ else parse_error("HEADELLIPSE parameter ymin missing ", list_name, line_number);
+ if(s) { s = next_word(token, s, buffer_size); xmax = atoi(token); }
+ else parse_error("HEADELLIPSE parameter xmax missing ", list_name, line_number);
+ if(s) { s = next_word(token, s, buffer_size); ymax = atoi(token); }
+ else parse_error("HEADELLIPSE parameter ymax missing ", list_name, line_number);
+ current_image->get_target_pose(nb_cats)->_head_xc = (xmin + xmax)/2;
+ current_image->get_target_pose(nb_cats)->_head_yc = (ymin + ymax)/2;
+ current_image->get_target_pose(nb_cats)->_head_radius = int(sqrt(scalar_t(xmax - xmin) * scalar_t(ymax - ymin))/2);
+ head_defined = true;
+ }
+
+ else if(strcmp(token, "BELLYLOCATION") == 0) {
+ if(!open_current_cat) parse_error("Undefined cat ", list_name, line_number);
+ int x1 = -1, y1 = -1;
+
+ if(s) { s = next_word(token, s, buffer_size); x1 = atoi(token); }
+ else parse_error("BELLYLOCATION parameter x1 missing ", list_name, line_number);
+ if(s) { s = next_word(token, s, buffer_size); y1 = atoi(token); }
+ else parse_error("BELLYLOCATION parameter y1 missing ", list_name, line_number);
+
+ if(body_defined) {
+ parse_error("More than one body location. ", list_name, line_number);
+ } else {
+
+ Pose *pose = current_image->get_target_pose(nb_cats);
+
+ pose->_body_xc = x1;
+ pose->_body_yc = y1;
+
+ body_defined = true;
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+
+int main(int argc, char **argv) {
+ char *new_argv[argc];
+ int new_argc = 0;
+
+ {
+ ParamParser parser;
+ global.init_parser(&parser);
+ parser.parse_options(argc, argv, false, &new_argc, new_argv);
+ global.read_parser(&parser);
+ cout << "-- PARAMETERS --------------------------------------------------------" << endl;
+ parser.print_all(&cout);
+ }
+
+ if(new_argc != 4) {
+ cerr << new_argv[0] << " <list file> <image path> <pool name>" << endl;
+ exit(1);
+ }
+
+ cout << "From list " << new_argv[1]
+ << " and image dir " << new_argv[2]
+ << ", generating pool " << new_argv[3]
+ << "." << endl;
+
+ cout << "-- GENERATING IMAGES -------------------------------------------------" << endl;
+
+ list_to_pool(new_argv[2], new_argv[1], new_argv[3]);
+
+ cout << "-- FINISHED ----------------------------------------------------------" << endl;
+
+}