gabor.cc

Go to the documentation of this file.
00001 
00003 
00004 //
00005 // Copyright (c) 1999-2004 California Institute of Technology
00006 // Copyright (c) 2004-2007 University of Southern California
00007 // Rob Peters <rjpeters at usc dot edu>
00008 //
00009 // created: Wed Oct  6 10:45:58 1999
00010 // commit: $Id: gabor.cc 10065 2007-04-12 05:54:56Z rjpeters $
00011 // $HeadURL: file:///lab/rjpeters/svnrepo/code/trunk/groovx/src/visx/gabor.cc $
00012 //
00013 // --------------------------------------------------------------------
00014 //
00015 // This file is part of GroovX.
00016 //   [http://ilab.usc.edu/rjpeters/groovx/]
00017 //
00018 // GroovX is free software; you can redistribute it and/or modify it
00019 // under the terms of the GNU General Public License as published by
00020 // the Free Software Foundation; either version 2 of the License, or
00021 // (at your option) any later version.
00022 //
00023 // GroovX is distributed in the hope that it will be useful, but
00024 // WITHOUT ANY WARRANTY; without even the implied warranty of
00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00026 // General Public License for more details.
00027 //
00028 // You should have received a copy of the GNU General Public License
00029 // along with GroovX; if not, write to the Free Software Foundation,
00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
00031 //
00033 
00034 #ifndef GROOVX_VISX_GABOR_CC_UTC20050626084017_DEFINED
00035 #define GROOVX_VISX_GABOR_CC_UTC20050626084017_DEFINED
00036 
00037 #include "visx/gabor.h"
00038 
00039 #include "geom/rect.h"
00040 #include "geom/vec3.h"
00041 
00042 #include "gfx/bbox.h"
00043 #include "gfx/canvas.h"
00044 #include "gfx/gxscaler.h"
00045 
00046 #include "io/ioproxy.h"
00047 #include "io/reader.h"
00048 #include "io/writer.h"
00049 
00050 #include "media/bmapdata.h"
00051 #include "media/imgfile.h"
00052 
00053 #include "rutz/algo.h"
00054 #include "rutz/rand.h"
00055 
00056 #include <cmath>
00057 
00058 #include "rutz/trace.h"
00059 #include "rutz/debug.h"
00060 GVX_DBG_REGISTER
00061 
00062 using geom::vec2i;
00063 using geom::vec2d;
00064 using geom::vec3d;
00065 
00066 namespace
00067 {
00068   const io::version_id GABOR_SVID = 2;
00069 }
00070 
00071 const Gabor::ColorMode Gabor::GRAYSCALE;
00072 const Gabor::ColorMode Gabor::COLOR_INDEX;
00073 const Gabor::ColorMode Gabor::BW_DITHER_POINT;
00074 const Gabor::ColorMode Gabor::BW_DITHER_RECT;
00075 
00076 const FieldMap& Gabor::classFields()
00077 {
00078   static const Field FIELD_ARRAY[] =
00079   {
00080     Field("colorMode", &Gabor::itsColorMode, 2, 1, 4, 1, Field::NEW_GROUP),
00081     Field("contrast", &Gabor::itsContrast, 1.0, 0.0, 1.0, 0.05),
00082     Field("logContrast",
00083           &Gabor::getLogContrast, &Gabor::setLogContrast,
00084           0.0, -3.0, 0.0, 0.1, Field::TRANSIENT),
00085     Field("spatialFreq", &Gabor::itsSpatialFreq, 3.5, 0.5, 10.0, 0.5),
00086     Field("phase", &Gabor::itsPhase, 0, 0, 359, 1),
00087     Field("drift", &Gabor::itsDrift, 0, 0, 359, 1, Field::TRANSIENT),
00088     Field("sigma", &Gabor::itsSigma, 0.15, 0.025, 0.5, 0.025),
00089     Field("aspectRatio", &Gabor::itsAspectRatio, 1.0, 0.1, 10.0, 0.1),
00090     Field("orientation", &Gabor::itsOrientation, 0, -180, 179, 1),
00091     Field("resolution", &Gabor::itsResolution, 60, 5, 500, 1),
00092     Field("pointSize", &Gabor::itsPointSize, 1, 1, 25, 1),
00093     Field("fgTint", Field::ValueType(), &Gabor::itsFgTint,
00094            "1.0 1.0 1.0 1.0", "0.0 0.0 0.0 0.0", "1.0 1.0 1.0 1.0",
00095           "0.01 0.01 0.01 0.01", Field::NEW_GROUP | Field::MULTI),
00096     Field("bgTint", Field::ValueType(), &Gabor::itsBgTint,
00097            "0.0 0.0 0.0 0.0", "0.0 0.0 0.0 0.0", "1.0 1.0 1.0 1.0",
00098           "0.01 0.01 0.01 0.01", Field::MULTI)
00099   };
00100 
00101   static FieldMap GABOR_FIELDS(FIELD_ARRAY, &GxShapeKit::classFields());
00102 
00103   return GABOR_FIELDS;
00104 }
00105 
00106 Gabor* Gabor::make()
00107 {
00108 GVX_TRACE("Gabor::make");
00109   return new Gabor;
00110 }
00111 
00112 Gabor::Gabor() :
00113   itsColorMode(1),
00114   itsContrast(1.0),
00115   itsSpatialFreq(3.5),
00116   itsPhase(0),
00117   itsDrift(0),
00118   itsDrawnPhase(0),
00119   itsSigma(0.15),
00120   itsAspectRatio(1.0),
00121   itsOrientation(0),
00122   itsResolution(116),
00123   itsPointSize(2),
00124   itsFgTint(1.0, 1.0, 1.0, 1.0),
00125   itsBgTint(0.0, 0.0, 0.0, 0.0)
00126 {
00127 GVX_TRACE("Gabor::Gabor");
00128 
00129   setFieldMap(Gabor::classFields());
00130 
00131   setScalingMode(GxScaler::MAINTAIN_ASPECT_SCALING);
00132 }
00133 
00134 Gabor::~Gabor () throw()
00135 {
00136 GVX_TRACE("Gabor::~Gabor");
00137 }
00138 
00139 io::version_id Gabor::class_version_id() const
00140 {
00141 GVX_TRACE("Gabor::class_version_id");
00142   return GABOR_SVID;
00143 }
00144 
00145 void Gabor::read_from(io::reader& reader)
00146 {
00147 GVX_TRACE("Gabor::read_from");
00148 
00149   reader.ensure_version_id("Gabor", 2,
00150                            "Try cvs tag xml_conversion_20040526",
00151                            SRC_POS);
00152 
00153   readFieldsFrom(reader, classFields());
00154 
00155   reader.read_base_class("GxShapeKit", io::make_proxy<GxShapeKit>(this));
00156 }
00157 
00158 void Gabor::write_to(io::writer& writer) const
00159 {
00160 GVX_TRACE("Gabor::write_to");
00161 
00162   writer.ensure_output_version_id("Gabor", GABOR_SVID, 2,
00163                               "Try groovx0.8a4", SRC_POS);
00164 
00165   writeFieldsTo(writer, classFields(), GABOR_SVID);
00166 
00167   writer.write_base_class("GxShapeKit", io::make_const_proxy<GxShapeKit>(this));
00168 }
00169 
00170 void Gabor::setLogContrast(double logContrast)
00171 {
00172 GVX_TRACE("Gabor::setLogContrast");
00173 
00174   if (logContrast <= 0.0)
00175     {
00176       itsContrast = std::pow(10.0, logContrast);
00177     }
00178 }
00179 
00180 double Gabor::getLogContrast() const
00181 {
00182 GVX_TRACE("getLogContrast");
00183 
00184   return (itsContrast > 0.0) ? std::log10(itsContrast) : -10.0;
00185 }
00186 
00187 void Gabor::grGetBoundingBox(Gfx::Bbox& bbox) const
00188 {
00189 GVX_TRACE("Gabor::grGetBoundingBox");
00190 
00191   bbox.drawScreenRect(vec3d::zeros(),
00192                       vec2i::ones() * itsResolution,
00193                       vec2d::ones() * itsPointSize);
00194 }
00195 
00196 void Gabor::getBmapData(media::bmap_data& dest) const
00197 {
00198 GVX_TRACE("Gabor::getBmapData");
00199   const double xsigma2 = itsSigma*itsAspectRatio * itsSigma*itsAspectRatio;
00200   const double ysigma2 = itsSigma * itsSigma;
00201 
00202   const vec2d center(0.0, 0.0);
00203 
00204   static const double PI = acos(-1.0);
00205 
00206   if (itsDrift == 0)
00207     {
00208       itsDrawnPhase = itsPhase;
00209     }
00210   else
00211     {
00212       itsDrawnPhase += itsDrift;
00213       itsDrawnPhase %= 360;
00214     }
00215 
00216   //                      1            ( -(x-mean)^2 / (2*sigma)^2 )
00217   // gaussian(x) = ---------------- * e
00218   //               sigma*sqrt(2*pi)
00219 
00220   // For our purposes, we ignore the scaling factor out front, so that
00221   // the maximum value the function takes on is 1 (the scaling factor
00222   // is otherwise there to keep the total area under the curve to 1,
00223   // but this affects the maximum height).
00224 
00225   const double res_step = 1.0/itsResolution;
00226 
00227   const vec2i size(itsResolution, itsResolution);
00228 
00229   const int bits_per_pixel = (itsColorMode == GRAYSCALE) ? 32 : 8;
00230 
00231   media::bmap_data data(size, bits_per_pixel, 1);
00232 
00233   typedef unsigned char ubyte;
00234 
00235   ubyte* bytes = data.bytes_ptr();
00236 
00237   ubyte* bytes_end = bytes + data.byte_count();
00238 
00239   for (int y_pos = 0; y_pos < itsResolution; ++y_pos)
00240     {
00241       const double unrotated_y = y_pos*res_step - 0.5;
00242 
00243       for (int x_pos = 0; x_pos < itsResolution; ++x_pos)
00244         {
00245           const double unrotated_x = x_pos*res_step - 0.5;
00246 
00247           vec2d point(unrotated_x, unrotated_y);
00248           point.rotate_deg(itsOrientation);
00249 
00250           point -= center;
00251 
00252           const double gauss_xy =
00253             exp( (point.x())*(point.x()) / (-4.0*xsigma2) +
00254                  (point.y())*(point.y()) / (-4.0*ysigma2) );
00255 
00256           const double sin_x =
00257             sin(2*PI*itsSpatialFreq*point.x() + itsDrawnPhase*PI/180.0);
00258 
00259           const double gabor = 0.5*sin_x*gauss_xy*itsContrast + 0.5;
00260 
00261           GVX_ASSERT( bytes < bytes_end );
00262 
00263           if ( itsColorMode == GRAYSCALE )
00264             {
00265               *bytes++ = ubyte
00266                 ((itsFgTint.color().r() * gabor +
00267                   itsBgTint.color().r() * (1-gabor)) * 255);
00268               *bytes++ = ubyte
00269                 ((itsFgTint.color().g() * gabor +
00270                   itsBgTint.color().g() * (1-gabor)) * 255);
00271               *bytes++ = ubyte
00272                 ((itsFgTint.color().b() * gabor +
00273                   itsBgTint.color().b() * (1-gabor)) * 255);
00274               *bytes++ = ubyte
00275                 ((itsFgTint.color().a() * gabor +
00276                   itsBgTint.color().a() * (1-gabor)) * 255);
00277             }
00278           else if ( itsColorMode == COLOR_INDEX )
00279             {
00280               *bytes++ = ubyte(gabor * 255);
00281             }
00282           else if ( itsColorMode == BW_DITHER_POINT ||
00283                     itsColorMode == BW_DITHER_RECT )
00284             {
00285               *bytes++ = (rutz::rand_range(0.0, 1.0) < gabor) ? 255 : 0;
00286             }
00287         }
00288     }
00289 
00290   data.swap(dest);
00291 }
00292 
00293 void Gabor::saveImage(const char* filename) const
00294 {
00295 GVX_TRACE("Gabor::saveImage");
00296 
00297   media::bmap_data data;
00298   getBmapData(data);
00299 
00300   media::save_image(filename, data);
00301 }
00302 
00303 void Gabor::grRender(Gfx::Canvas& canvas) const
00304 {
00305 GVX_TRACE("Gabor::grRender");
00306 
00307   media::bmap_data data;
00308   getBmapData(data);
00309 
00310   canvas.drawPixels(data, vec3d::zeros(),
00311                     vec2d(itsPointSize, itsPointSize));
00312 }
00313 
00314 static const char __attribute__((used)) vcid_groovx_visx_gabor_cc_utc20050626084017[] = "$Id: gabor.cc 10065 2007-04-12 05:54:56Z rjpeters $ $HeadURL: file:
00315 #endif // !GROOVX_VISX_GABOR_CC_UTC20050626084017_DEFINED

The software described here is Copyright (c) 1998-2005, Rob Peters.
This page was generated Wed Dec 3 06:49:42 2008 by Doxygen version 1.5.5.