retinafilt.C

Go to the documentation of this file.
00001 /*!@file TestSuite/retinafilt.C Apply a retinalike transformation to an image */
00002 
00003 //////////////////////////////////////////////////////////////////////////
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 //////////////////////////////////////////////////////////////////////////
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 //////////////////////////////////////////////////////////////////////////
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 //////////////////////////////////////////////////////////////////////////
00032 //
00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/TestSuite/retinafilt.C $
00035 // $Id: retinafilt.C 12074 2009-11-24 07:51:51Z itti $
00036 //
00037 
00038 #include "Image/Image.H"
00039 #include "Image/ImageSet.H"
00040 #include "Image/Pixels.H"
00041 #include "Image/PyramidOps.H"
00042 #include "Raster/Raster.H"
00043 
00044 #include <algorithm> // for std::min
00045 #include <cmath>
00046 #include <cstdio>
00047 #include <typeinfo>
00048 
00049 //! depth of the pyramid used to obtain the eccentricity-dependent resolution
00050 #define PYR_DEPTH 10
00051 
00052 //! blind spot center, as a factor of image width and height, from center
00053 #define BLIND_X 0.15f
00054 #define BLIND_Y 0.00f
00055 
00056 //! blind spot 2*sigma^2, in pixels
00057 #define BLIND_2S2 600.0f
00058 
00059 //! fovea 2*sigma^2, in pixels:
00060 #define FOVEA_2S2 150.0f
00061 
00062 
00063 template <class T>
00064 void showtypeof(T t, const char* expr)
00065 {
00066   LINFO("type of %s is %s", expr, typeid(T).name());
00067 }
00068 
00069 #define SHOWTYPEOF(x) showtypeof(x, #x)
00070 
00071 /* ###################################################################### */
00072 int main(int argc, char **argv)
00073 {
00074   bool fovea_blue = false, blind_spot = false;
00075   if (argc < 3) {
00076     fprintf(stderr,
00077             "USAGE: %s [opts] <input.ppm> <output.ppm> [fov_x fov_y]\n"
00078             "options:\n"
00079             "      -b implement blind spot\n"
00080             "      -f no blue cones in fovea\n", argv[0]);
00081     exit(1);
00082   }
00083   int ar = 1;
00084   if (argv[ar][0] == '-') {
00085     for (unsigned int ii = 1; ii < strlen(argv[ar]); ii ++) {
00086       switch (argv[ar][ii]) {
00087       case 'b': blind_spot = true; break;
00088       case 'f': fovea_blue = true; break;
00089       default: LFATAL("Unknown option '%c'.", argv[ar][ii]);
00090       }
00091     }
00092     ar ++;
00093   }
00094 
00095   // read input image:
00096   Image< PixRGB<byte> > input = Raster::ReadRGB(argv[ar++]);
00097 
00098   // create gaussian pyramid and destination image:
00099   ImageSet< PixRGB<byte> > pyr = buildPyrGaussian(input, 0, PYR_DEPTH, 5);
00100 
00101   // apply radial smoothing:
00102   int w = input.getWidth(), h = input.getHeight(), ci = w / 2, cj = h / 2;
00103 
00104   // use given fovea center if present in params:
00105   if (argc - ar > 1)
00106     {
00107       ci = atoi(argv[ar + 1]); ci = std::max(0, std::min(w-1, ci));
00108       cj = atoi(argv[ar + 2]); cj = std::max(0, std::min(h-1, cj));
00109       LINFO("Using (%d, %d) for fovea center", ci, cj);
00110     }
00111 
00112   Image< PixRGB<byte> > output(w, h, NO_INIT);
00113   float rstep = float(std::max(w, h) / PYR_DEPTH);
00114   int bi = ci + int(w * BLIND_X), bj = cj + int(h * BLIND_Y);
00115 
00116   for (int i = 0; i < w; i ++)
00117     for (int j = 0; j < h; j ++)
00118       {
00119         float dist = sqrtf((i-ci)*(i-ci) + (j-cj)*(j-cj));
00120 
00121         // determine resolution from which this pixel will be taken:
00122         float d = dist / rstep;
00123 
00124         // get the pixel value from depth d:
00125         int di = int(d);
00126         float dd = d - float(di);
00127 
00128         // uncomment these 2 lines for radial pixelization:
00129         //int ii=(i/(1<<di))*(1<<di), jj=(j/(1<<di))*(1<<di);
00130         //if (ii-i<(1<<di) && jj-j<(1<<di)) d=0.0f; else d=1.0f;
00131 
00132         Point2D<int> loc(i, j);
00133         PixRGB<byte> pix0 = getPyrPixel(pyr, loc, di);
00134         PixRGB<byte> pix1 = getPyrPixel(pyr, loc, std::min(di+1, PYR_DEPTH-1));
00135 
00136         float blind = 1.0f;
00137         if (blind_spot)
00138           blind = 1.0f - expf(-((i-bi)*(i-bi) + (j-bj)*(j-bj)) / BLIND_2S2);
00139 
00140         static bool didit = false;
00141 
00142         if (!didit)
00143           {
00144             SHOWTYPEOF(pix0);
00145             SHOWTYPEOF(pix1);
00146             SHOWTYPEOF(pix1-pix0);
00147             SHOWTYPEOF((pix1-pix0)*dd);
00148             SHOWTYPEOF(pix0 + (pix1-pix0)*dd);
00149             SHOWTYPEOF((pix0 + (pix1-pix0)*dd) * blind);
00150             didit = true;
00151           }
00152 
00153         PixRGB<byte> pix( (pix0 + (pix1 - pix0) * dd) * blind );
00154         if (fovea_blue)
00155           pix.setBlue(pix.blue() * (1.0f - expf(-dist * dist / FOVEA_2S2)));
00156 
00157         // for Nature Reviews Neuroscience paper: neuron-cam mode
00158         //if (dist > 20.0) {
00159         //pix /= exp((dist - 20.0f) / 10.0f);
00160         //}
00161 
00162         // store:
00163         output.setVal(loc, pix);
00164       }
00165 
00166   // write out result:
00167   Raster::WriteRGB(output, argv[ar], RASFMT_PNM);
00168   return 0;
00169 }
00170 
00171 
00172 // ######################################################################
00173 /* So things look consistent in everyone's emacs... */
00174 /* Local Variables: */
00175 /* indent-tabs-mode: nil */
00176 /* End: */
Generated on Sun May 8 08:42:22 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3