testHaarStump.cc

  1 const char *help = "\
  2 progname: testHaarStump.cc\n\
  3 code2html: This program tests a linear combinaison of Haar-like classifiers.\n\
  4 version: Torch3 vision2.0, 2004-2005\n\
  5 (c) Sebastien Marcel (marcel@idiap.ch) and Yann Rodriguez (rodrig@idiap.ch)\n";
  6 
  7 // Torch
  8 
  9 // command-lines
 10 #include "FileListCmdOption.h"
 11 #include "CmdLine.h"
 12 
 13 /** Torch3vision
 14 */
 15 
 16 // Stump machines
 17 #include "HaarStumpMachine.h"
 18 #include "HaarRealStumpMachine.h"
 19 #include "ImageWeightedSumMachine.h"
 20 
 21 // datasets
 22 //#include "FileBinDataSet.h"
 23 #include "DiskBinDataSet.h"
 24 
 25 // image processing
 26 #include "ipIntegralImage.h"
 27 #include "ipNormMeanStdvLight.h"
 28 
 29 using namespace Torch;
 30 
 31 int main(int argc, char **argv)
 32 {
 33    	//
 34    	int width;
 35 	int height;
 36 
 37 	//
 38 	char *model_filename;
 39 
 40 	//
 41 	bool image_normalize;
 42 	bool haar_normalize;
 43 	bool realstump;
 44 
 45 	//
 46 	char *output_basename;
 47 	int n_histo_bins;
 48 
 49 	//
 50 	bool verbose;
 51 
 52 	Allocator *allocator = new Allocator;
 53 
 54 	FileListCmdOption filelist_class("file name", "the list files or one data file of patterns");
 55 	filelist_class.isArgument(true);
 56 
 57 	//
 58 	// Prepare the command-line
 59 	CmdLine cmd;
 60 	cmd.setBOption("write log", false);
 61 	cmd.info(help);
 62 	cmd.addText("\nArguments:");
 63 	cmd.addSCmdArg("model", &model_filename, "model filename");
 64 	cmd.addCmdOption(&filelist_class);
 65 	cmd.addICmdArg("width", &width, "width");
 66 	cmd.addICmdArg("height", &height, "height");
 67 	cmd.addText("\nOptions:");
 68 	cmd.addBCmdOption("-real", &realstump, false, "uses real stump");
 69 	cmd.addBCmdOption("-imagenorm", &image_normalize, false, "considers the input pattern as an image and performs a photometric normalization");
 70 	cmd.addBCmdOption("-haarnorm", &haar_normalize, false, "normalize feature outputs");
 71   	cmd.addICmdOption("-nbins", &n_histo_bins, 100, "number of patterns to output");
 72   	cmd.addBCmdOption("-verbose", &verbose, false, "verbose");
 73   	cmd.addSCmdOption("-o", &output_basename, "test", "output basename");
 74 
 75 	//
 76 	// Read the command-line
 77 	cmd.read(argc, argv);
 78 
 79 	if((image_normalize && haar_normalize) || (!image_normalize && !haar_normalize))
 80 	{
 81 		warning("choose between image and haar normalization.\n");
 82 
 83 		return 0;
 84 	}
 85 	
 86 	//
 87         print("n_filenames = %d\n", filelist_class.n_files);
 88         for(int i = 0 ; i < filelist_class.n_files ; i++)
 89                 print("   filename[%d] = %s\n", i, filelist_class.file_names[i]);
 90 
 91 	//
 92 	int n_trainers;
 93 	int n_inputs = width * height;
 94 
 95 	//FileBinDataSet *data = NULL;
 96 	DiskBinDataSet *data = NULL;
 97 	//data = new(allocator) FileBinDataSet(filelist_class.file_names, filelist_class.n_files, n_inputs);
 98 	data = new(allocator) DiskBinDataSet(filelist_class.file_names, filelist_class.n_files, n_inputs, -1);
 99 
100         data->info(false);
101 
102 	//
103 	print("Pre-processing ...\n");
104    	ipCore *inorm_machine = NULL;
105 	ipCore *i_machine = NULL;
106 	real *integralimage2 = NULL;
107 
108 	if(haar_normalize)
109 	{
110 		i_machine = new(allocator) ipIntegralImage(width, height, "gray", true);
111 	   	integralimage2 = i_machine->seq_out->frames[1];
112 	}
113 	else i_machine = new(allocator) ipIntegralImage(width, height, "gray");
114 
115 	if(image_normalize)
116 	{
117 		inorm_machine = new(allocator) ipNormMeanStdvLight(width, height, "float");
118 		inorm_machine->setBOption("verbose", verbose);
119 	}
120 	
121 	//
122 	print("Loading model %s ...\n", model_filename);
123 	
124 	DiskXFile *model = new(allocator) DiskXFile(model_filename, "r");
125 	model->taggedRead(&n_inputs, sizeof(int), 1, "N_INPUTS");
126 	model->taggedRead(&n_trainers, sizeof(int), 1, "N_TRAINERS");
127 
128 	print(" + n_inputs = %d\n", n_inputs);
129 	print(" + n_trainers = %d\n", n_trainers);
130 	
131 
132 	//
133 	Machine **machines = (Machine **)allocator->alloc(n_trainers*sizeof(Machine *));
134 	for(int j = 0 ; j < n_trainers ; j++)
135 	   	if(realstump)
136 			machines[j] = new(allocator) HaarRealStumpMachine(width, height, integralimage2);
137 		else machines[j] = new(allocator) HaarStumpMachine(width, height, integralimage2);
138 	ImageWeightedSumMachine *iwsm = new(allocator) ImageWeightedSumMachine(machines, n_trainers);
139 
140 	//
141 	iwsm->loadXFile(model);
142 
143 	if(verbose)
144 	{
145 		for(int j = 0 ; j < n_trainers ; j++)
146 		{
147 	   		if(realstump)
148 			{
149 	   			HaarRealStumpMachine *h_ = (HaarRealStumpMachine *) machines[j];
150 				h_->the_mask->info();
151 			}
152 			else
153 			{
154 	   			HaarStumpMachine *h_ = (HaarStumpMachine *) machines[j];
155 				h_->the_mask->info();
156 			}
157 		}
158 	}
159 
160 	//
161 	real min_ = 1000.0;
162 	real max_ = -1000.0;
163 
164 	//
165 	real *outputs = (real *) allocator->alloc(data->n_examples * sizeof(real));
166 
167 	//
168 	char output_filename[250];
169 	sprintf(output_filename, "%s.output", output_basename);
170 	DiskXFile *pf_output = new(allocator) DiskXFile(output_filename, "w");
171 
172 	for(int i=0; i<data->n_examples; i++)
173         {
174 		data->setExample(i);
175 		real *input_ = data->inputs->frames[0];
176 		
177 		Sequence *seqinput = data->inputs;
178 
179 		if(image_normalize)
180 		{
181 			inorm_machine->process(seqinput);
182 			
183 			input_ = inorm_machine->seq_out->frames[0];			
184 
185 			seqinput = inorm_machine->seq_out;
186 		}
187 
188 		// computes integral image
189 		i_machine->process(seqinput);
190 
191 		// remplace the input by its integral image
192 		real *output_ = i_machine->seq_out->frames[0];
193 		for(int j = 0 ; j < width * height ; j++)
194 			data->inputs->frames[0][j] = output_[j];
195 	
196 		// forward
197 		iwsm->forward(data->inputs);
198 
199 		outputs[i] = iwsm->outputs->frames[0][0];
200 
201 	   	if(verbose) 
202 			print(" -> %g\n", outputs[i]);
203 
204 		pf_output->printf("%g\n", outputs[i]);
205 
206 		if(i == 0)
207 		{
208 			min_ = outputs[i];
209 			max_ = outputs[i];
210 		}
211 		else
212 		{
213 			if(outputs[i] < min_) min_ = outputs[i];
214 			if(outputs[i] > max_) max_ = outputs[i];
215 		}
216 	}
217 	
218 	print("min = %g\n", min_);
219 	print("max = %g\n", max_);
220 
221 	//
222 	int *histo = (int *) allocator->alloc(n_histo_bins * sizeof(int));
223 	for(int i = 0 ; i < n_histo_bins ; i++) histo[i] = 0;
224 
225 	//
226 	real n_1 = n_histo_bins - 1;
227 	for(int i = 0 ; i < data->n_examples ; i++)
228 	{
229 		int index = FixI(n_1 * (outputs[i] - min_) / (max_ - min_));
230 
231 		histo[index]++;
232 	}
233 
234 	//
235 	real histo_max_ = 0.0;
236 	for(int i = 0 ; i < n_histo_bins ; i++)
237 		if(histo[i] > histo_max_) histo_max_ = histo[i];
238 
239 	//
240 	char histo_filename[250];
241 	sprintf(histo_filename, "%s.histo", output_basename);
242 	DiskXFile *pf_histo = new(allocator) DiskXFile(histo_filename, "w");
243 
244 	for(int i = 0 ; i < n_histo_bins ; i++)
245 		if(histo[i] != 0)
246 		{
247 			real output_ = (real) i * (max_ - min_) / n_1 + min_;
248 			
249 			real histo_ = (real) histo[i] / histo_max_;
250 			//real histo_ = (real) histo[i] / (real) data->n_examples;
251 
252 			pf_histo->printf("%g %g\n", output_, histo_);
253 		}
254 
255 	//
256   	delete allocator;
257 
258   	return(0);
259 }