00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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
00217
00218
00219
00220
00221
00222
00223
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