relaxation.cc

  1 const char *help = "\
  2 progname: relaxation.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 Gauss-Seidel relaxation).\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 the Gauss-Seidel relaxation method. 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 "ipRelaxation.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   real lambda;
 29   bool verbose;
 30   int type;
 31   int steps;
 32   bool light;
 33   bool histo;
 34 
 35   // --------------------- COMMAND LINE -------------------------------------------------------------------------
 36   CmdLine cmd;
 37   cmd.setBOption("write log", false);
 38   cmd.info(help);
 39 
 40   cmd.addText("\nArguments:");
 41   cmd.addSCmdArg("image_filename", &image_filename, "input image filename");
 42   cmd.addSCmdArg("out_filename", &out_filename, "processed image filename");
 43 
 44   cmd.addText("\nOptions:");
 45   cmd.addICmdOption("-steps", &steps, 20, "numbers of relaxation steps");
 46   cmd.addBCmdOption("-verbose", &verbose, false, "verbose");
 47   cmd.addRCmdOption("-lambda", &lambda, 1, "relative importance of the smoothness constraint");
 48   cmd.addICmdOption("-type", &type, 1, "type of diffusion: 0 = Isotropic, 1 = Anisotropic (Weber contrast)");
 49   cmd.addBCmdOption("-light", &light, false, "saves the light estimate image");
 50   cmd.addBCmdOption("-histo", &histo, false, "performs histogram equalization on the result");
 51   
 52   cmd.read(argc, argv);
 53   
 54   Timer timer;
 55 
 56   Allocator *allocator = new Allocator;
 57   // ----------------------- LOAD IMAGE --------------------------------------------------------------------------
 58   DiskXFile *image_file = NULL;
 59   Image *image_in = NULL;
 60 
 61   image_in = new(allocator) ImageGray();
 62   image_in->setBOption("verbose", verbose);
 63 	
 64   image_file = new(allocator) DiskXFile(image_filename, "r");
 65   image_in->loadXFile(image_file);
 66 
 67   if(verbose)
 68     {
 69       print("Image info:\n");
 70       print("   width = %d\n", image_in->width);
 71       print("   height = %d\n", image_in->height);
 72       print("   format = %s (%d)\n", image_in->coding, image_in->n_planes);
 73     }
 74   
 75   
 76 
 77   // ---------------------- PROCESSING IMAGE MACHINE ------------------------------------------------------------	
 78   ipCore *relax = NULL;
 79   relax = new(allocator) ipRelaxation(lambda, type, steps, image_in->width, image_in->height, "gray");
 80   relax->setBOption("verbose", verbose);
 81   relax->process(image_in);
 82 
 83   ipCore *histoEq = NULL;
 84    
 85   if (histo) {   
 86     histoEq = new(allocator) ipHistoEqual(image_in->width, image_in->height, "gray");
 87     histoEq->process(relax->seq_out);
 88   }
 89 
 90 
 91 
 92   // ----------------------- SAVE IMAGE(S)  --------------------------------------------------------------------------
 93   Image *image_out = NULL;
 94   image_out = new(allocator) ImageGray();
 95   image_out->setBOption("verbose", verbose);
 96 
 97   if (histo)
 98     image_out->copyFrom(image_in->width, image_in->height, histoEq->seq_out->frames[0], "gray", 255);
 99   else
100     image_out->copyFrom(image_in->width, image_in->height, relax->seq_out->frames[0], "gray", 255);
101  
102   image_out->updatePixmapFromData();
103   image_out->save(out_filename);
104 
105   print("time elapsed: %g\n", timer.getTime());
106 
107   if (light) {
108     image_out->copyFrom(image_in->width, image_in->height, relax->seq_out->frames[1], "gray", 255);
109     image_out->updatePixmapFromData();
110     image_out->save("light_estimate.pgm");
111   }
112 
113   // ---------------------- CLEAN UP -----------------------------------------------------------------------------
114   delete allocator;
115   	
116   return(0);	
117 }