diffusionVcycle.cc

  1 const char *help = "\
  2 progname: diffusionVcycle.cc\n\
  3 code2html: This program reads a pgm image (grayscale) and normalizes the lighting conditions according to the Gross and Brajovic algorithm (resolution with multigrid V-cycle).\n\
  4 \n\
  5 A diffusion process is applied to the input image, in order to find the luminance estimate.\n\
  6 The discretized version of the PDE describing the diffusion process is solved using\n\
  7 a multigrid v-cycle approach. The input image is then divided by the luminance estimate\n\
  8 so as to find the reflectance estimate (illumination free)\n\
  9 'Gross and Brajovic [2003] - Preprocessing algorithm for Illumination Invariant Face Recognition'\n\
 10 \n\
 11 version: Torch3 vision2.0, 2004-2005\n\
 12 (c) Guillaume Heusch (heusch@idiap.ch)\n";
 13 
 14 #include "ImageGray.h"
 15 #include "DiskXFile.h"
 16 #include "CmdLine.h"
 17 #include "ipVcycle.h"
 18 #include "ipHistoEqual.h"
 19 #include "Timer.h"
 20 
 21 using namespace Torch;
 22 
 23 int main(int argc, char **argv)
 24 {
 25   
 26   char *image_filename;
 27   char *out_filename;
 28  
 29   // relative importance of the smoothness constraint
 30   real lambda;
 31 
 32   // number of grids in the V-cycle
 33   int n_grids;
 34 
 35   /* type of diffusion performed (coefficients)
 36   - 0 = isotropic
 37   - 1 = Perona-Malik's exponential
 38   - 2 = inverse Weber contrast 
 39   - 3 = inverse Michelson contrast
 40   */
 41   int type;
 42   
 43   bool verbose;
 44   bool light; // if you want to save the estimated light
 45   bool histo; // if you want to apply equalization on the normalized image
 46 
 47  
 48   // --------------------- COMMAND LINE -------------------------------------------------------------------------
 49   CmdLine cmd;
 50   cmd.setBOption("write log", false);
 51   cmd.info(help);
 52 
 53   cmd.addText("\nArguments:");
 54   cmd.addSCmdArg("image_filename", &image_filename, "input image filename");
 55   cmd.addSCmdArg("out_filename", &out_filename, "processed image filename");
 56 
 57   cmd.addText("\nOptions:");
 58   cmd.addBCmdOption("-verbose", &verbose, false, "verbose");
 59   cmd.addRCmdOption("-lambda", &lambda, 0.001, "relative importance of the smoothness constraint");
 60   cmd.addICmdOption("-n_grids", &n_grids, 5, "number of levels (WARNING: dependant on input image)");
 61   cmd.addICmdOption("-type", &type, 1, "type of diffusion: 0 = Isotropic, 1 = Perona-Malik, 2 = Weber, 3 = Michelson");
 62   cmd.addBCmdOption("-light", &light, false, "saves the light estimate image");
 63   cmd.addBCmdOption("-histo", &histo, false, "performs histogram equalization on the result");
 64  
 65   cmd.read(argc, argv);
 66   
 67   Allocator *allocator = new Allocator;
 68   
 69   Timer timer;
 70 
 71   // ----------------------- LOAD IMAGE --------------------------------------------------------------------------
 72   DiskXFile *image_file = NULL;
 73   Image *image_in = NULL;
 74 
 75   image_in = new(allocator) ImageGray();
 76   image_in->setBOption("verbose", verbose);
 77 	
 78   image_file = new(allocator) DiskXFile(image_filename, "r");
 79   image_in->loadXFile(image_file);
 80 
 81   if(verbose)
 82     {
 83       print("Image info:\n");
 84       print("   width = %d\n", image_in->width);
 85       print("   height = %d\n", image_in->height);
 86       print("   format = %s (%d)\n", image_in->coding, image_in->n_planes);
 87     }
 88   
 89   
 90 
 91   // ---------------------- PROCESSING IMAGE MACHINE ------------------------------------------------------------	
 92   ipCore *vcycle = NULL;
 93   vcycle = new(allocator) ipVcycle(lambda, n_grids, type, image_in->width, image_in->height, "gray");
 94   vcycle->setBOption("verbose", verbose);
 95   vcycle->process(image_in);
 96 
 97   ipCore *histoEq = NULL;
 98    
 99   if (histo) {   
100     histoEq = new(allocator) ipHistoEqual(image_in->width, image_in->height, "gray");
101     histoEq->process(vcycle->seq_out);
102   }
103 
104 
105 
106   // ----------------------- SAVE IMAGE(S)  --------------------------------------------------------------------------
107   Image *image_out = NULL;
108   image_out = new(allocator) ImageGray();
109   image_out->setBOption("verbose", verbose);
110 
111    if (histo)
112     image_out->copyFrom(image_in->width, image_in->height, histoEq->seq_out->frames[0], "gray", 255);
113   else
114     image_out->copyFrom(image_in->width, image_in->height, vcycle->seq_out->frames[0], "gray", 255);
115  
116   image_out->updatePixmapFromData();
117   image_out->save(out_filename);
118 
119   print("time elapsed: %g\n", timer.getTime());
120 
121   if (light) {
122     image_out->copyFrom(image_in->width, image_in->height, vcycle->seq_out->frames[1], "gray", 255);
123     image_out->updatePixmapFromData();
124     image_out->save("light_estimate.pgm");
125   }
126   
127   delete allocator;
128   	
129   return(0);	
130 }