ClassicSearchItem.C

Go to the documentation of this file.
00001 /*!@file Psycho/ClassicSearchItem.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/Psycho/ClassicSearchItem.C $
00035 // $Id: ClassicSearchItem.C 9079 2007-12-12 00:54:09Z rjpeters $
00036 //
00037 
00038 #ifndef PSYCHO_CLASSICSEARCHITEM_C_DEFINED
00039 #define PSYCHO_CLASSICSEARCHITEM_C_DEFINED
00040 
00041 #include "Psycho/ClassicSearchItem.H"
00042 
00043 #include "Image/Image.H"
00044 #include "Image/ShapeOps.H"
00045 
00046 #include <cmath>
00047 
00048 namespace
00049 {
00050   Image<double> makeC(int sz, const double angle)
00051   {
00052     Image<double> result(sz, sz, NO_INIT);
00053 
00054     Image<double>::iterator ptr = result.beginw();
00055 
00056     const double ro2 = (0.25 * sz) * (0.25 * sz);
00057     const double ri2 = (0.2 * sz) * (0.2 * sz);
00058     const double xc = 0.5 * sz - 0.5;
00059     const double yc = 0.5 * sz - 0.5;
00060 
00061     for (int y = 0; y < sz; ++y)
00062       {
00063         const double y2 = (y-yc)*(y-yc);
00064 
00065         for (int x = 0; x < sz; ++x)
00066           {
00067             const double r2 = (x-xc)*(x-xc) + y2;
00068 
00069             const double theta = atan2(yc-y, x-xc);
00070 
00071             const double diff = geom::rad_npi_pi(geom::rad_npi_pi(angle) - theta);
00072 
00073             if (fabs(diff) > M_PI/8.0 &&
00074                 r2 > ri2 && r2 <= ro2)
00075               *ptr++ = -1.0;
00076             else
00077               *ptr++ = 0.0;
00078           }
00079       }
00080 
00081     return result;
00082   }
00083 
00084   Image<double> makeO(int sz)
00085   {
00086     Image<double> result(sz, sz, NO_INIT);
00087 
00088     Image<double>::iterator ptr = result.beginw();
00089 
00090     const double ro2 = (0.25 * sz) * (0.25 * sz);
00091     const double ri2 = (0.2 * sz) * (0.2 * sz);
00092     const double xc = 0.5 * sz - 0.5;
00093     const double yc = 0.5 * sz - 0.5;
00094 
00095     for (int y = 0; y < sz; ++y)
00096       {
00097         const double y2 = (y-yc)*(y-yc);
00098 
00099         for (int x = 0; x < sz; ++x)
00100           {
00101             const double r2 = (x-xc)*(x-xc) + y2;
00102 
00103             if (r2 > ri2 && r2 <= ro2)
00104               *ptr++ = -1.0;
00105             else
00106               *ptr++ = 0.0;
00107           }
00108       }
00109 
00110     return result;
00111   }
00112 
00113   Image<double> makeQ(int sz, const double angle)
00114   {
00115     Image<double> result(sz, sz, NO_INIT);
00116 
00117     Image<double>::iterator ptr = result.beginw();
00118 
00119     const double cosa = cos(-angle);
00120     const double sina = sin(-angle);
00121     const double ro2 = (0.25 * sz) * (0.25 * sz);
00122     const double ri2 = (0.2 * sz) * (0.2 * sz);
00123     const double xc = 0.5 * sz - 0.5;
00124     const double yc = 0.5 * sz - 0.5;
00125 
00126     const double dh = 0.025 * sz;
00127 
00128     for (int y = 0; y < sz; ++y)
00129       {
00130         const double y2 = (y-yc)*(y-yc);
00131 
00132         for (int x = 0; x < sz; ++x)
00133           {
00134             const double r2 = (x-xc)*(x-xc) + y2;
00135 
00136             const double u = (x-xc) * cosa - (yc-y) * sina;
00137             const double v = (x-xc) * sina + (yc-y) * cosa;
00138 
00139             if ((r2 > ri2 && r2 <= ro2)
00140                 ||
00141                 (fabs(v) <= dh && fabs(u-0.225*sz) < 0.1*sz))
00142               *ptr++ = -1.0;
00143             else
00144               *ptr++ = 0.0;
00145           }
00146       }
00147 
00148     return result;
00149   }
00150 
00151   Image<double> makePlus(int sz, const double angle)
00152   {
00153     Image<double> result(sz, sz, NO_INIT);
00154 
00155     Image<double>::iterator ptr = result.beginw();
00156 
00157     const double cosa = cos(-angle);
00158     const double sina = sin(-angle);
00159     const double xc = 0.5 * sz - 0.5;
00160     const double yc = 0.5 * sz - 0.5;
00161 
00162     const double dh = 0.025 * sz;
00163     const double dw = 0.25 * sz;
00164 
00165     for (int y = 0; y < sz; ++y)
00166       for (int x = 0; x < sz; ++x)
00167         {
00168           const double u = (x-xc) * cosa - (yc-y) * sina;
00169           const double v = (x-xc) * sina + (yc-y) * cosa;
00170 
00171           if ((fabs(u) <= dw && fabs(v) <= dh)
00172               ||
00173               (fabs(v) <= dw && fabs(u) <= dh))
00174             *ptr++ = -1.0;
00175           else
00176             *ptr++ = 0.0;
00177         }
00178 
00179     return result;
00180   }
00181 
00182   Image<double> makeL(int sz, const double angle)
00183   {
00184     Image<double> result(sz, sz, NO_INIT);
00185 
00186     Image<double>::iterator ptr = result.beginw();
00187 
00188     const double cosa = cos(-angle);
00189     const double sina = sin(-angle);
00190     const double xc = 0.5 * sz - 0.5;
00191     const double yc = 0.5 * sz - 0.5;
00192 
00193     const double dh = 0.025 * sz;
00194     const double dw = 0.25 * sz;
00195 
00196     for (int y = 0; y < sz; ++y)
00197       for (int x = 0; x < sz; ++x)
00198         {
00199           const double u = (x-xc) * cosa - (yc-y) * sina;
00200           const double v = (x-xc) * sina + (yc-y) * cosa;
00201 
00202           if ((fabs(u+0.225*sz) <= dh && fabs(v) <= dw)
00203               ||
00204               (fabs(v+0.225*sz) <= dh && fabs(u) <= dw))
00205             *ptr++ = -1.0;
00206           else
00207             *ptr++ = 0.0;
00208         }
00209 
00210     return result;
00211   }
00212 
00213   Image<double> makeT(int sz, const double angle)
00214   {
00215     Image<double> result(sz, sz, NO_INIT);
00216 
00217     Image<double>::iterator ptr = result.beginw();
00218 
00219     const double cosa = cos(-angle);
00220     const double sina = sin(-angle);
00221     const double xc = 0.5 * sz - 0.5;
00222     const double yc = 0.5 * sz - 0.5;
00223 
00224     const double dh = 0.025 * sz;
00225     const double dw = 0.25 * sz;
00226 
00227     for (int y = 0; y < sz; ++y)
00228       for (int x = 0; x < sz; ++x)
00229         {
00230           const double u = (x-xc) * cosa - (yc-y) * sina;
00231           const double v = (x-xc) * sina + (yc-y) * cosa;
00232 
00233           if ((fabs(u) <= dh && fabs(v) <= dw)
00234               ||
00235               (fabs(v-0.225*sz) <= dh && fabs(u) <= dw))
00236             *ptr++ = -1.0;
00237           else
00238             *ptr++ = 0.0;
00239         }
00240 
00241     return result;
00242   }
00243 
00244   Image<double> makeDash(int sz, const double angle)
00245   {
00246     Image<double> result(sz, sz, NO_INIT);
00247 
00248     Image<double>::iterator ptr = result.beginw();
00249 
00250     const double cosa = cos(-angle);
00251     const double sina = sin(-angle);
00252     const double xc = 0.5 * sz - 0.5;
00253     const double yc = 0.5 * sz - 0.5;
00254 
00255     const double dh = 0.025 * sz;
00256     const double dw = 0.25 * sz;
00257 
00258     for (int y = 0; y < sz; ++y)
00259       for (int x = 0; x < sz; ++x)
00260         {
00261           const double u = (x-xc) * cosa - (yc-y) * sina;
00262           const double v = (x-xc) * sina + (yc-y) * cosa;
00263 
00264           if (fabs(u) <= dw && fabs(v) <= dh)
00265             *ptr++ = -1.0;
00266           else
00267             *ptr++ = 0.0;
00268         }
00269 
00270     return result;
00271   }
00272 
00273   Image<double> shrink(const Image<double>& img, int noctaves)
00274   {
00275     Image<double> result = img;
00276     for (int i = 0; i < noctaves; ++i)
00277       result = quickLocalAvg2x2(result);
00278     return result;
00279   }
00280 }
00281 
00282 // ######################################################################
00283 ClassicSearchItem::ClassicSearchItem(Type t, int sz, double angle,
00284                                      int antialiasOctaves)
00285   :
00286   itsType(t),
00287   itsSize(sz),
00288   itsAngle(angle),
00289   itsAntialiasOctaves(antialiasOctaves)
00290 {}
00291 
00292 // ######################################################################
00293 ClassicSearchItem::~ClassicSearchItem()
00294 {}
00295 
00296 // ######################################################################
00297 Image<double> ClassicSearchItem::getPatch() const
00298 {
00299   const int zoom = (1 << itsAntialiasOctaves);
00300 
00301   switch (itsType)
00302     {
00303     case ITEM_C: return shrink(makeC(itsSize*zoom, itsAngle), itsAntialiasOctaves);
00304     case ITEM_O: return shrink(makeO(itsSize*zoom), itsAntialiasOctaves);
00305     case ITEM_Q: return shrink(makeQ(itsSize*zoom, itsAngle), itsAntialiasOctaves);
00306     case ITEM_PLUS: return shrink(makePlus(itsSize*zoom, itsAngle), itsAntialiasOctaves);
00307     case ITEM_L: return shrink(makeL(itsSize*zoom, itsAngle), itsAntialiasOctaves);
00308     case ITEM_T: return shrink(makeT(itsSize*zoom, itsAngle), itsAntialiasOctaves);
00309     case ITEM_DASH: return shrink(makeDash(itsSize*zoom, itsAngle), itsAntialiasOctaves);
00310     default:
00311       break;
00312     }
00313 
00314   LFATAL("unsupported item type");
00315   /* can't happen */ return Image<double>();
00316 }
00317 
00318 // ######################################################################
00319 ClassicSearchItem::Type ClassicSearchItem::typeFromChar(char c)
00320 {
00321   switch (toupper(c))
00322     {
00323     case 'C': return ITEM_C;
00324     case 'O': return ITEM_O;
00325     case 'Q': return ITEM_Q;
00326     case '+': return ITEM_PLUS;
00327     case 'L': return ITEM_L;
00328     case 'T': return ITEM_T;
00329     case '-': return ITEM_DASH;
00330     }
00331 
00332   LFATAL("invalid search item type '%c'", c);
00333   /* can't happen */ return Type(-1);
00334 }
00335 
00336 // ######################################################################
00337 ClassicSearchItemFactory::ClassicSearchItemFactory(SearchItem::Type c,
00338                                                    const std::string& types,
00339                                                    int sz,
00340                                                    const Range<double>& angleRange,
00341                                                    int antialiasOctaves,
00342                                                    int angleSeed,
00343                                                    int typeSeed)
00344   :
00345   itsLayer(c),
00346   itsTypeList(types),
00347   itsSize(sz),
00348   itsAngleRange(angleRange),
00349   itsAntialiasOctaves(antialiasOctaves),
00350   itsAngles(angleSeed),
00351   itsTypes(typeSeed)
00352 {
00353   if (itsTypeList.size() == 0)
00354     LFATAL("search item typelist must include at least one type");
00355 }
00356 
00357 // ######################################################################
00358 ClassicSearchItemFactory::~ClassicSearchItemFactory()
00359 {}
00360 
00361 // ######################################################################
00362 rutz::shared_ptr<SearchItem> ClassicSearchItemFactory::make(const geom::vec2d& pos)
00363 {
00364   ClassicSearchItem::Type t =
00365     ClassicSearchItem::typeFromChar(itsTypeList[itsTypes.idraw(itsTypeList.size())]);
00366 
00367   rutz::shared_ptr<ClassicSearchItem> el
00368     (new ClassicSearchItem(t, itsSize,
00369                            itsAngles.fdraw_range(itsAngleRange.min(), itsAngleRange.max()),
00370                            itsAntialiasOctaves));
00371 
00372   el->type = itsLayer;
00373   el->pos = pos;
00374 
00375   return el;
00376 }
00377 
00378 // ######################################################################
00379 /* So things look consistent in everyone's emacs... */
00380 /* Local Variables: */
00381 /* mode: c++ */
00382 /* indent-tabs-mode: nil */
00383 /* End: */
00384 
00385 #endif // PSYCHO_CLASSICSEARCHITEM_C_DEFINED
Generated on Sun May 8 08:41:12 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3