00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <iostream>
00022 #include "vigra/stdimage.hxx"
00023 #include "vigra/resizeimage.hxx"
00024 #include "vigra/impex.hxx"
00025 #include "vigra/colorconversions.hxx"
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028 #include <stdlib.h>
00029 #include "Gabor.h"
00030 #include "Utilities.h"
00031 #include "CelesteGlobals.h"
00032
00033 using namespace vigra;
00034 using namespace std;
00035
00036 void usage (char* filename){
00037
00038 cout << "Usage: " << filename << " <image file> <mask file>" << endl;
00039 cout << "or for a positive example: " << filename << " -p <image file>" << endl;
00040 cout << "or for a negative example: " << filename << " -n <image file>" << endl;
00041 cout << "(supported formats: " << vigra::impexListFormats() << ")" << endl;
00042 }
00043
00044 int main(int argc, char ** argv){
00045
00046 unsigned int a = 1;
00047 unsigned int pos = 0;
00048 unsigned int neg = 0;
00049 string image_file,mask_file;
00050 vigra::FRGBImage mask_in;
00051 vigra::FRGBImage::iterator mask_iter;
00052
00053
00054 if(argc < 3 || argc >= 4){
00055
00056 usage(argv[0]); exit(1);
00057 }
00058
00059 while( a < argc ){
00060
00061 if( argv[a][0] == '-'){
00062
00063 a++;
00064 switch(argv[a-1][1]){
00065
00066
00067 case 'h' : {usage(argv[0]); exit(1);}
00068 case 'p' : {pos = 1;
00069 cerr << "Ignoring mask. Image is a positive example." << endl;
00070 image_file = argv[argc-1];
00071 break;
00072 }
00073 case 'n' : {neg = 1;
00074 cerr << "Ignoring mask. Image is a negative example." << endl;
00075 image_file = argv[argc-1];
00076 break;
00077 }
00078 default : {usage(argv[0]); exit(1);}
00079 }
00080
00081 }
00082
00083 a++;
00084 }
00085
00086 if (pos == 0 && neg == 0){
00087
00088 image_file = argv[argc-2];
00089 mask_file = argv[argc-1];
00090
00091
00092
00093
00094 }
00095
00096 try{
00097
00098 cerr << "Opening image file: " << image_file << endl;
00099
00100
00101
00102 vigra::ImageImportInfo info(image_file.c_str());
00103
00104
00105 vigra::FRGBImage in(info.width(), info.height());
00106
00107
00108 importImage(info, destImage(in));
00109
00110
00111 if (pos == 0 && neg == 0){
00112
00113 cerr << "Opening mask file: " << mask_file << endl;
00114
00115
00116 vigra::ImageImportInfo mask_info(mask_file.c_str());
00117
00118
00119 if (info.width() != mask_info.width() || info.height() != mask_info.height()){
00120
00121 cerr << "Error - image and mask files are different dimension:" << endl;
00122 cerr << "Image:\t" << info.width() << " x " << info.height() << endl;
00123 cerr << "Mask:\t" << mask_info.width() << " x " << mask_info.height() << endl << endl;
00124 return 1;
00125
00126 }
00127
00128
00129 vigra::FRGBImage tmp_mask_in(info.width(), info.height());
00130
00131 importImage(mask_info, destImage(tmp_mask_in));
00132 mask_in = tmp_mask_in;
00133
00134 }
00135
00136
00137
00138 const int resize_dimension = 800;
00139
00140
00141 if (info.width() >= resize_dimension || info.height() >= resize_dimension){
00142
00143
00144
00145 int method = 0;
00146 double sizefactor;
00147
00148 if (info.width() >= info.height()){
00149 sizefactor = (double)resize_dimension/info.width();
00150 }else{
00151 sizefactor = (double)resize_dimension/info.height();
00152 }
00153
00154
00155 int nw = (int)(sizefactor*info.width());
00156 int nh = (int)(sizefactor*info.height());
00157
00158 cerr << "Image dimensions:\t" << info.width() << " x " << info.height() << endl;
00159 cerr << "Scaling by:\t\t" << sizefactor << endl;
00160 cerr << "New dimensions:\t\t" << nw << " x " << nh << endl;
00161
00162
00163 vigra::FRGBImage out(nw, nh);
00164
00165 switch(method){
00166
00167 case 0:
00168
00169 resizeImageNoInterpolation(srcImageRange(in),destImageRange(out));
00170 break;
00171
00172 case 1:
00173
00174 resizeImageLinearInterpolation(srcImageRange(in),destImageRange(out));
00175 break;
00176
00177 default:
00178
00179 resizeImageSplineInterpolation(srcImageRange(in),destImageRange(out));
00180 }
00181
00182 in = out;
00183
00184
00185 if (pos == 0 && neg == 0){
00186
00187 vigra::FRGBImage mask_out(nw, nh);
00188
00189 switch(method){
00190
00191 case 0:
00192
00193 resizeImageNoInterpolation(srcImageRange(mask_in),destImageRange(mask_out));
00194 break;
00195
00196 case 1:
00197
00198 resizeImageLinearInterpolation(srcImageRange(mask_in),destImageRange(mask_out));
00199 break;
00200
00201 default:
00202
00203 resizeImageSplineInterpolation(srcImageRange(mask_in),destImageRange(mask_out));
00204
00205 }
00206
00207 mask_in = mask_out;
00208 }
00209
00210 }else{
00211 cerr << "Image dimensions:\t" << info.width() << " x " << info.height() << endl;
00212 }
00213
00214 cerr << "Total pixels:\t\t" << in.width()*in.height() << endl;
00215
00216
00217 cerr << "Converting to LUV colourspace..." << endl;
00218
00219 FRGBImage luv(in.width(),in.height());
00220 transformImage(srcImageRange(in), destImage(luv), RGBPrime2LuvFunctor<double>() );
00221
00222
00223 cerr << "Generating fiducial points..." << endl;
00224
00225 for (int i = gRadius; i < in.height() - gRadius; i += spacing ){
00226 for (int j = gRadius; j < in.width() - gRadius; j += spacing ){
00227 gNumLocs++;
00228 }
00229 }
00230
00231
00232 gLocations = CreateMatrix( (int)0, gNumLocs, 2);
00233 gNumLocs = 0;
00234 for (int i = gRadius; i < in.height() - gRadius; i += spacing ){
00235 for (int j = gRadius; j < in.width() - gRadius; j += spacing ){
00236
00237 gLocations[gNumLocs][0] = j;
00238 gLocations[gNumLocs][1] = i;
00239
00240
00241
00242 gNumLocs++;
00243 }
00244 }
00245 cerr << "Total fiducial points: " << gNumLocs << endl;
00246
00247
00248 float *frameBuf = new float[in.width()*in.height()];
00249 float *u_values = new float[in.width()*in.height()];
00250 float *v_values = new float[in.width()*in.height()];
00251
00252
00253 float** pixels = CreateMatrix( (float)0, in.height(), in.width() );
00254
00255
00256 int counter = 0;
00257 vigra::FRGBImage::iterator img_iter(luv.begin()),end(luv.end());
00258 for(; img_iter != end; ++img_iter) {
00259
00260
00261
00262 frameBuf[counter] = (*img_iter)[0];
00263
00264 u_values[counter] = (*img_iter)[1];
00265 v_values[counter] = (*img_iter)[2];
00266
00267
00268
00269
00270 counter++;
00271 }
00272
00273
00274 int k = 0;
00275 for (int i = 0; i < in.height(); i++ ){
00276 for (int j = 0; j < in.width(); j++ ){
00277 pixels[i][j] = frameBuf[k];
00278
00279 k++;
00280 }
00281 }
00282
00283 char basename[] = "gabor_filters/celeste";
00284
00285 float *response = NULL;
00286 int len = 0;
00287
00288 response = ProcessChannel( pixels, in.height(), in.width(), response, &len, basename );
00289
00290
00291 if (pos == 0 && neg == 0){
00292
00293
00294 vigra::FRGBImage::iterator tmp_mask_iter(mask_in.begin()),mask_end(mask_in.end());
00295 mask_iter = tmp_mask_iter;
00296 mask_end = NULL;
00297 }
00298
00299 cerr << "Generating feature vector by Gabor filtering..." << endl;
00300
00301
00302 int vector_length = (int)len/gNumLocs;
00303 for ( int j = 0; j < gNumLocs; j++ ){
00304
00305
00306
00307 int pixel_number = gLocations[j][0] + (in.width() * (gLocations[j][1] - 1)) - 1;
00308
00309
00310 if (pos){
00311 cout << "+1 ";
00312 }else if (neg){
00313 cout << "-1 ";
00314 }else{
00315
00316 if (mask_iter[pixel_number][0] != 0 || mask_iter[pixel_number][1] != 0 || mask_iter[pixel_number][2] != 0){
00317
00318 cout << "-1 ";
00319 }else{
00320
00321 cout << "+1 ";
00322 }
00323 }
00324
00325 int feature = 1;
00326 for ( int v = (j * vector_length); v < ((j + 1) * vector_length); v++){
00327 cout << feature << ":" << response[v] << " ";
00328 feature++;
00329 }
00330
00331
00332
00333 float u_sum = 0, v_sum = 0;
00334 int pixels_in_region = (gRadius * 2)*(gRadius * 2);
00335
00336
00337
00338
00339
00340 for (int t = 1 - gRadius; t <= gRadius; t++){
00341
00342 int this_y_pixel = pixel_number + (t * in.width());
00343
00344
00345 for (int r = 1 - gRadius; r <= gRadius; r++){
00346
00347 int this_x_pixel = this_y_pixel + r;
00348
00349
00350
00351
00352
00353
00354
00355 u_sum += u_values[this_x_pixel];
00356 v_sum += v_values[this_x_pixel];
00357
00358
00359
00360
00361 }
00362
00363 }
00364
00365
00366 float u_ave = (float)u_sum/pixels_in_region;
00367 float v_ave = (float)v_sum/pixels_in_region;
00368
00369
00370 u_sum = 0, v_sum = 0;
00371
00372 for (int t = 1 - gRadius; t <= gRadius; t++){
00373 int this_y_pixel = pixel_number + (t * in.width());
00374
00375 for (int r = 1 - gRadius; r <= gRadius; r++){
00376
00377 int this_x_pixel = this_y_pixel + r;
00378
00379 u_sum += pow(u_values[this_x_pixel]-u_ave,2);
00380 v_sum += pow(v_values[this_x_pixel]-v_ave,2);
00381
00382 }
00383 }
00384
00385
00386 float std_u = sqrt(u_sum/(pixels_in_region-1));
00387 float std_v = sqrt(v_sum/(pixels_in_region-1));
00388
00389
00390
00391
00392 cout << feature << ":" << u_ave << " ";
00393 feature++;
00394 cout << feature << ":" << std_u << " ";
00395 feature++;
00396 cout << feature << ":" << v_ave << " ";
00397 feature++;
00398 cout << feature << ":" << std_v << " ";
00399 feature++;
00400
00401
00402
00403 cout << feature << ":" << u_values[pixel_number] << " ";
00404 feature++;
00405 cout << feature << ":" << v_values[pixel_number] << " ";
00406 feature++;
00407
00408
00409
00410
00411
00412 cout << endl;
00413 }
00414
00415 delete[] response;
00416 delete[] frameBuf;
00417 delete[] u_values;
00418 delete[] v_values;
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430 }catch (vigra::StdException & e){
00431
00432
00433 std::cout << e.what() << std::endl;
00434 return 1;
00435
00436 }
00437
00438 return 0;
00439
00440 }