Update for recent libpng
[svrt.git] / vision_problem_3.cc
1 /*
2  *  svrt is the ``Synthetic Visual Reasoning Test'', an image
3  *  generator for evaluating classification performance of machine
4  *  learning systems, humans and primates.
5  *
6  *  Copyright (c) 2009 Idiap Research Institute, http://www.idiap.ch/
7  *  Written by Francois Fleuret <francois.fleuret@idiap.ch>
8  *
9  *  This file is part of svrt.
10  *
11  *  svrt is free software: you can redistribute it and/or modify it
12  *  under the terms of the GNU General Public License version 3 as
13  *  published by the Free Software Foundation.
14  *
15  *  svrt 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.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with svrt.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  */
24
25 #include "vision_problem_3.h"
26 #include "shape.h"
27
28 VisionProblem_3::VisionProblem_3() { }
29
30 void VisionProblem_3::generate(int label, Vignette *vignette) {
31   int nb_shapes = 4;
32   Vignette avoid, tmp;
33   const int dist_min = Vignette::width / 8;
34
35   int nb_attempts;
36   const int max_nb_attempts = 100;
37
38   do {
39     avoid.clear();
40     vignette->clear();
41
42     nb_attempts = 0;
43
44     for(int s = 0; nb_attempts < max_nb_attempts && s < nb_shapes; s++) {
45       Shape shape;
46
47       int xs, ys, i, right_margin, right_connection;
48
49       do {
50         tmp.clear();
51         do {
52           do {
53             xs = int(drand48() * Vignette::width);
54             ys = int(drand48() * Vignette::height);
55             shape.randomize(part_size, hole_size);
56           }  while(shape.overwrites(&tmp, xs, ys)); // check not out-of-vignette
57
58           // omg this is ugly
59           if(label && s == 1) {
60             right_margin = 1;
61           } else {
62             right_margin = !shape.overwrites(&avoid, xs, ys);
63           }
64
65           if((label && (s == 1 || s == 3)) || (!label && (s >= 2))) {
66             right_connection = shape.overwrites(vignette, xs, ys);
67           } else {
68             right_connection = 1;
69           }
70
71           nb_attempts++;
72
73         } while(nb_attempts < max_nb_attempts && !right_margin);
74
75         shape.draw(&tmp, xs, ys);
76         tmp.fill(xs, ys, 0);
77
78         if(right_margin && right_connection) {
79           if((label && (s == 1 || s == 3)) || (!label && (s >= 2))) {
80             i = vignette->intersection(&tmp);
81             right_connection = (i > 0) && (i < 4);
82           } else {
83             right_connection = 1;
84           }
85         } else right_connection = 0; // To avoid compilation warning
86       } while(nb_attempts < max_nb_attempts && (!right_margin || !right_connection));
87
88       if(nb_attempts < max_nb_attempts) {
89         shape.draw(vignette, xs, ys);
90         vignette->fill(xs, ys, 128);
91         if((label && s < 2) || (!label && s < 1)) {
92           for(int k = 0; k < dist_min; k++) tmp.grow();
93           avoid.superpose(&avoid, &tmp);
94         }
95       }
96     }
97   } while(nb_attempts >= max_nb_attempts);
98
99   vignette->replace_value(128, 255);
100 }