LogPolarTransform.C

Go to the documentation of this file.
00001 /*!@file Image/LogPolarTransform.C */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the 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: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/LogPolarTransform.C $
00035 // $Id: LogPolarTransform.C 9993 2008-07-29 00:04:18Z lior $
00036 //
00037 
00038 #ifndef IMAGE_LOGPOLARTRANSFORM_C_DEFINED
00039 #define IMAGE_LOGPOLARTRANSFORM_C_DEFINED
00040 
00041 #include "Image/LogPolarTransform.H"
00042 
00043 #include "Image/MathOps.H"
00044 #include "Image/Pixels.H"
00045 #include "Image/Range.H"
00046 #include "Util/MathFunctions.H"
00047 
00048 #include <algorithm>
00049 #include <cmath>
00050 #include <utility>
00051 #include <vector>
00052 
00053 // ######################################################################
00054 LogPolarTransform::LogPolarTransform(const Dims& indims, const Dims& outdims,
00055                                      const double deg_per_pixel,
00056                                      const double step)
00057   :
00058   itsInDims(indims),
00059   itsOutDims(outdims)
00060 {
00061   const int w = indims.w();
00062   const int h = indims.h();
00063 
00064   Range<double> xrng;
00065   Range<double> yrng;
00066 
00067   const double A = 3.0;
00068   const double B_x = 1.4;
00069   const double B_y = 1.8;
00070 
00071   for (int j = 0; j < h; ++j)
00072     for (int i = 0; i < w; ++i)
00073       {
00074         if (j > 0 && j < h-1 && i > 0 && i < w-1)
00075           continue;
00076 
00077         const double x = (i - w / 2.0) * deg_per_pixel;
00078         const double y = (j - h / 2.0) * deg_per_pixel;
00079 
00080         const double sx = (x < 0.0) ? 1.0 : -1.0;
00081 
00082         const double r = sqrt(x*x + y*y);
00083         const double th = atan2(y, fabs(x));
00084 
00085         const double X = sx * B_x * log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A);
00086         const double Y = -B_y * atan(r*sin(th) / (r*cos(th) + A));
00087 
00088         // (s * X / B_x) = log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A)
00089         // exp(s* X / B_x) = sqrt(r*r + 2*A*r*cos(th) + A*A) / A
00090         // A * exp(s* X / B_x) = sqrt(r*r + 2*A*r*cos(th) + A*A)
00091 
00092         xrng.merge(X);
00093         yrng.merge(Y);
00094       }
00095 
00096   const double scale = std::min((outdims.w() - 1) / xrng.range(),
00097                                 (outdims.h() - 1) / yrng.range());
00098 
00099   const int dw = outdims.w();
00100 
00101   for (double j = 0; j < h; j += step)
00102     for (double i = 0; i < w; i += step)
00103       {
00104         const double x = (i - w / 2.0) * (120.0 / w);
00105         const double y = (j - h / 2.0) * (120.0 / h);
00106 
00107         const double sx = (x < 0.0) ? 1.0 : -1.0;
00108 
00109         const double r = sqrt(x*x + y*y);
00110         const double th = atan2(y, fabs(x));
00111 
00112         const double X = sx * B_x * log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A);
00113         const double Y = -B_y * atan(r*sin(th) / (r*cos(th) + A));
00114 
00115         if (!isFinite(X))
00116           LINFO("i,j = %f,%f", i, j);
00117 
00118         // (s * X / B_x) = log(sqrt(r*r + 2*A*r*cos(th) + A*A) / A)
00119         // exp(s* X / B_x) = sqrt(r*r + 2*A*r*cos(th) + A*A) / A
00120         // A * exp(s* X / B_x) = sqrt(r*r + 2*A*r*cos(th) + A*A)
00121 
00122         const int NX = int((X - xrng.min()) * scale);
00123         const int NY = int((Y - yrng.min()) * scale);
00124 
00125         itsCoords.push_back(std::make_pair(int(j)*w + int(i), NY*dw + NX));
00126       }
00127 }
00128 
00129 // ######################################################################
00130 template <class T>
00131 Image<T> logPolarTransform(const LogPolarTransform& t,
00132                            const Image<T>& inp, const T bkg_color)
00133 {
00134   ASSERT(inp.getDims() == t.itsInDims);
00135 
00136   typedef typename promote_trait<T, double>::TP TF;
00137 
00138   Image<TF> txf(t.itsOutDims, ZEROS);
00139   Image<int> counts(t.itsOutDims, ZEROS);
00140 
00141   typename Image<T>::const_iterator sptr = inp.begin();
00142   typename Image<TF>::iterator txfitr = txf.beginw();
00143   Image<int>::iterator citr = counts.beginw();
00144 
00145   for (size_t n = 0; n < t.itsCoords.size(); ++n)
00146     {
00147       txfitr[t.itsCoords[n].second] += TF(sptr[t.itsCoords[n].first]);
00148       citr[t.itsCoords[n].second] += 1;
00149     }
00150 
00151   txfitr = txf.beginw();
00152   citr = counts.beginw();
00153 
00154   Image<T> btxf(txf.getDims(), ZEROS);
00155   typename Image<T>::iterator btxfitr = btxf.beginw();
00156 
00157   for (int j = 0; j < txf.getHeight(); ++j)
00158     for (int i = 0; i < txf.getWidth(); ++i)
00159       {
00160         if (*citr == 0)
00161           *btxfitr = bkg_color;
00162         else
00163           *btxfitr = T(*txfitr / double(*citr));
00164         ++btxfitr; ++txfitr; ++citr;
00165       }
00166 
00167   return btxf;
00168 }
00169 
00170 // Include the explicit instantiations
00171 #include "inst/Image/LogPolarTransform.I"
00172 
00173 // ######################################################################
00174 /* So things look consistent in everyone's emacs... */
00175 /* Local Variables: */
00176 /* mode: c++ */
00177 /* indent-tabs-mode: nil */
00178 /* End: */
00179 
00180 #endif // IMAGE_LOGPOLARTRANSFORM_C_DEFINED
Generated on Sun May 8 08:05:12 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3