00001
00002
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
00032
00033
00034
00035
00036
00037
00038 #ifndef NEURO_ENVVISUALCORTEX_C_DEFINED
00039 #define NEURO_ENVVISUALCORTEX_C_DEFINED
00040
00041 #include "Neuro/EnvVisualCortex.H"
00042
00043 #include "Component/ModelOptionDef.H"
00044 #include "Envision/env_c_math_ops.h"
00045 #include "Envision/env_image_ops.h"
00046 #include "Envision/env_job_server.h"
00047 #include "Envision/env_log.h"
00048 #include "Envision/env_mt_visual_cortex.h"
00049 #include "Envision/env_pthread_interface.h"
00050 #include "Envision/env_stdio_interface.h"
00051 #include "Neuro/EnvOpts.H"
00052 #include "Util/AllocAux.H"
00053 #include "Util/JobWithSemaphore.H"
00054 #include "Util/StringConversions.H"
00055 #include "Util/WorkThreadServer.H"
00056
00057 #include <cstdio>
00058 #include <sstream>
00059 #include <vector>
00060
00061
00062 const ModelOptionDef OPT_EvcMaxnormType =
00063 { MODOPT_ARG(std::string), "EvcMaxnormType", &MOC_ENVISION, OPTEXP_CORE,
00064 "Type of normalization to use",
00065 "evc-maxnorm-type", '\0', "<None|Maxnorm>", "Maxnorm" };
00066
00067
00068 const ModelOptionDef OPT_EvcScaleBits =
00069 { MODOPT_ARG(byte), "EvcScaleBits", &MOC_ENVISION, OPTEXP_CORE,
00070 "Number of bits of dynamic range to use",
00071 "evc-scale-bits", '\0', "<byte>", "16" };
00072
00073 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00074
00075
00076 const ModelOptionDef OPT_EvcNumDirections =
00077 { MODOPT_ARG(byte), "EvcNumDirections", &MOC_ENVISION, OPTEXP_CORE,
00078 "Number of motion directions to use",
00079 "evc-num-directions", '\0', "<byte>", "4" };
00080
00081
00082 const ModelOptionDef OPT_EvcMotionThresh =
00083 { MODOPT_ARG(byte), "EvcMotionThresh", &MOC_ENVISION, OPTEXP_CORE,
00084 "Low threshold cutoff for motion channel",
00085 "evc-motion-thresh", '\0', "<byte>", "12" };
00086
00087
00088 const ModelOptionDef OPT_EvcFlickerThresh =
00089 { MODOPT_ARG(byte), "EvcFlickerThresh", &MOC_ENVISION, OPTEXP_CORE,
00090 "Low threshold cutoff for flicker channel",
00091 "evc-flicker-thresh", '\0', "<byte>", "20" };
00092
00093
00094 const ModelOptionDef OPT_EvcRangeThresh =
00095 { MODOPT_ARG(int), "EvcRangeThresh", &MOC_ENVISION, OPTEXP_CORE,
00096 "Low threshold cutoff for normalizing maps. "
00097 "If the range of the map is bellow this threshold "
00098 "then the value would be set to 0.",
00099 "evc-range-thresh", '\0', "<int>", "0" };
00100
00101
00102 const ModelOptionDef OPT_EvcMultiScaleFlicker =
00103 { MODOPT_FLAG, "EvcMultiScaleFlicker", &MOC_ENVISION, OPTEXP_CORE,
00104 "Whether to use a true multi-scale flicker channel",
00105 "evc-multiscale-flicker", '\0', "", "true" };
00106
00107
00108 const ModelOptionDef OPT_EvcShowMemStats =
00109 { MODOPT_FLAG, "EvcShowMemStats", &MOC_ENVISION, OPTEXP_CORE,
00110 "Whether to show memory usage",
00111 "evc-show-memstats", '\0', "", "false" };
00112
00113 #endif
00114
00115
00116 const ModelOptionDef OPT_EvcNumOrientations =
00117 { MODOPT_ARG(byte), "EvcNumOrientations", &MOC_ENVISION, OPTEXP_CORE,
00118 "Number of orientation channels to use",
00119 "evc-num-orientations", '\0', "<byte>", "4" };
00120
00121
00122 const ModelOptionDef OPT_EvcType =
00123 { MODOPT_ARG(std::string), "EvcType", &MOC_ENVISION, OPTEXP_CORE,
00124 "A string containing one or more of the characters "
00125 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00126 "'I', 'C', 'O', 'F', and 'M', "
00127 #else
00128 "'I', 'C', and 'O', "
00129 #endif
00130 "indicating which of the intensity, color, orientation, flicker, "
00131 "and motion channels should be included, respectively. Additionally, "
00132 "each character can optionally be followed by a ':' and a "
00133 "floating-point number between 0.0 and 1.0 indicating the weight for "
00134 "that channel. By default, each channel receives a weight of 1.0.",
00135 "evc-type", '\0',
00136 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00137 "<I:wC:wO:wF:wM:w>", "ICOFM"
00138 #else
00139 "<I:wC:wO:w>", "ICO"
00140 #endif
00141 };
00142
00143
00144 const ModelOptionDef OPT_EvcColorSmoothing =
00145 { MODOPT_FLAG, "EvcColorSmoothing", &MOC_ENVISION, OPTEXP_CORE,
00146 "Whether to do two-frame smoothing of the color channel",
00147 "evc-color-smoothing", '\0', "", "false" };
00148
00149 const ModelOptionDef OPT_EvcOutputFactor =
00150 { MODOPT_ARG(float), "EvcOutputFactor", &MOC_ENVISION, OPTEXP_CORE,
00151 "Factor applied to outputs of EnvVisualCortexFloat to scale them to Amps of "
00152 "synaptic input currents to saliency map",
00153 "evc-outfac", '\0', "<float>", "5.0e-18" };
00154
00155
00156
00157 static void* malloc_thunk(env_size_t n)
00158 {
00159 return malloc(n);
00160 }
00161
00162
00163 static Image<byte> convert_gray(const struct env_image* iimage, const struct env_dims dims)
00164 {
00165 if (!env_img_initialized(iimage)) return Image<byte>(dims.w, dims.h, ZEROS);
00166
00167 Image<byte> result(iimage->dims.w, iimage->dims.h, NO_INIT);
00168
00169 const intg32* const src = env_img_pixels(iimage);
00170 const env_size_t sz = env_img_size(iimage);
00171 byte* bimage = result.getArrayPtr();
00172
00173 for (env_size_t i = 0; i < sz; ++i)
00174 {
00175
00176
00177 ENV_ASSERT(src[i] >= 0 && src[i] <= 255);
00178 bimage[i] = byte(src[i]);
00179 }
00180
00181 return result;
00182 }
00183
00184
00185 static Image<float> convert_gray_float(const struct env_image* iimage,
00186 const struct env_dims dims, const float factor)
00187 {
00188 if (!env_img_initialized(iimage)) return Image<float>(dims.w, dims.h, ZEROS);
00189
00190 Image<float> result(iimage->dims.w, iimage->dims.h, NO_INIT);
00191
00192 const intg32* src = env_img_pixels(iimage);
00193 const env_size_t sz = env_img_size(iimage);
00194 float* fimage = result.getArrayPtr();
00195 if (factor == 1.0F) for (env_size_t i = 0; i < sz; ++i) { *fimage = *src; ++fimage; ++src; }
00196 else for (env_size_t i = 0; i < sz; ++i) { *fimage = (*src) * factor; ++fimage; ++src; }
00197
00198 return result;
00199 }
00200
00201
00202 namespace
00203 {
00204 class EnvisionJob : public JobWithSemaphore
00205 {
00206 public:
00207 EnvisionJob(const struct env_job* j) : envJob(*j) {}
00208
00209 virtual ~EnvisionJob() {}
00210
00211 virtual void run()
00212 {
00213 (*envJob.callback)(envJob.userdata);
00214 this->markFinished();
00215 }
00216
00217 virtual const char* jobType() const { return "EnvisionJob"; }
00218
00219 const struct env_job envJob;
00220 };
00221 }
00222
00223
00224 static void workthread_job_server(void* job_server_data,
00225 const struct env_job* jobs,
00226 const env_size_t njobs)
00227 {
00228 if (njobs == 0) return;
00229
00230 WorkThreadServer* srv = static_cast<WorkThreadServer*>(job_server_data);
00231
00232 std::vector<rutz::shared_ptr<EnvisionJob> > ejobs;
00233 for (env_size_t i = 0; i < njobs; ++i)
00234 {
00235 ejobs.push_back(rutz::make_shared(new EnvisionJob(jobs + i)));
00236 srv->enqueueJob(ejobs.back());
00237 }
00238
00239 for (size_t i = 0; i < ejobs.size(); ++i) ejobs[i]->wait();
00240 }
00241
00242
00243 EnvVisualCortexBase::EnvVisualCortexBase(OptionManager& mgr, const std::string& descrName,
00244 const std::string& tagName) :
00245 ModelComponent(mgr, descrName, tagName),
00246 itsIweight("EvcIntensityWeight", this, 255, ALLOW_ONLINE_CHANGES),
00247 itsCweight("EvcColorWeight", this, 255, ALLOW_ONLINE_CHANGES),
00248 itsOweight("EvcOrientationWeight", this, 255, ALLOW_ONLINE_CHANGES),
00249 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00250 itsFweight("EvcFlickerWeight", this, 255, ALLOW_ONLINE_CHANGES),
00251 itsMweight("EvcMotionWeight", this, 255, ALLOW_ONLINE_CHANGES),
00252 #endif
00253 itsMultithreaded(&OPT_EvcMultithreaded, this, ALLOW_ONLINE_CHANGES),
00254 itsMaxnormType(&OPT_EvcMaxnormType, this),
00255 itsScaleBits(&OPT_EvcScaleBits, this),
00256 itsNumOrientations(&OPT_EvcNumOrientations, this, ALLOW_ONLINE_CHANGES),
00257 itsColorSmoothing(&OPT_EvcColorSmoothing, this, ALLOW_ONLINE_CHANGES),
00258 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00259 itsNumDirections(&OPT_EvcNumDirections, this, ALLOW_ONLINE_CHANGES),
00260 itsMotionThresh(&OPT_EvcMotionThresh, this, ALLOW_ONLINE_CHANGES),
00261 itsFlickerThresh(&OPT_EvcFlickerThresh, this, ALLOW_ONLINE_CHANGES),
00262 itsRangeThresh(&OPT_EvcRangeThresh, this, ALLOW_ONLINE_CHANGES),
00263 itsMultiScaleFlicker(&OPT_EvcMultiScaleFlicker, this, ALLOW_ONLINE_CHANGES),
00264 itsShowMemStats(&OPT_EvcShowMemStats, this, ALLOW_ONLINE_CHANGES),
00265 #endif
00266 itsLevelSpec(&OPT_EnvLevelSpec, this),
00267 itsType(&OPT_EvcType, this)
00268 {
00269 env_params_set_defaults(&this->envp);
00270 }
00271
00272
00273 EnvVisualCortexBase::~EnvVisualCortexBase()
00274 {
00275 itsThreadServer.reset(0);
00276 env_set_job_server(0, 0);
00277 env_allocation_cleanup();
00278 }
00279
00280
00281 void EnvVisualCortexBase::start1()
00282 {
00283 env_assert_set_handler(&env_stdio_assert_handler);
00284 env_allocation_init(&malloc_thunk, &free);
00285
00286 LINFO(".scale_bits = %u", (unsigned int) itsScaleBits.getVal());
00287
00288 this->envp.scale_bits = itsScaleBits.getVal();
00289 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00290 this->envp.num_motion_directions = itsNumDirections.getVal();
00291 this->envp.motion_thresh = itsMotionThresh.getVal();
00292 this->envp.flicker_thresh = itsFlickerThresh.getVal();
00293 this->envp.range_thresh = itsRangeThresh.getVal();
00294 this->envp.multiscale_flicker = itsMultiScaleFlicker.getVal() ? 1 : 0;
00295 #endif
00296 this->envp.num_orientations = itsNumOrientations.getVal();
00297 this->envp.cs_lev_min = itsLevelSpec.getVal().levMin();
00298 this->envp.cs_lev_max = itsLevelSpec.getVal().levMax();
00299 this->envp.cs_del_min = itsLevelSpec.getVal().delMin();
00300 this->envp.cs_del_max = itsLevelSpec.getVal().delMax();;
00301 this->envp.output_map_level = itsLevelSpec.getVal().mapLevel();
00302
00303 env_visual_cortex_init(&this->ivc, &this->envp);
00304
00305 this->npixels = 0;
00306
00307 this->framenum = 0;
00308
00309 itsIweight.setVal(this->envp.chan_i_weight);
00310 itsCweight.setVal(this->envp.chan_c_weight);
00311 itsOweight.setVal(this->envp.chan_o_weight);
00312 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00313 itsFweight.setVal(this->envp.chan_f_weight);
00314 itsMweight.setVal(this->envp.chan_m_weight);
00315 #endif
00316 }
00317
00318
00319 void EnvVisualCortexBase::stop2()
00320 {
00321 if (itsShowMemStats.getVal())
00322 {
00323 struct env_alloc_stats stats;
00324 env_allocation_get_stats(&stats);
00325 env_stdio_print_alloc_stats(&stats, this->npixels ? this->npixels : 1);
00326 invt_allocation_show_stats(1, "final", this->npixels);
00327 }
00328
00329 env_visual_cortex_destroy(&this->ivc);
00330 }
00331
00332
00333 void EnvVisualCortexBase::paramChanged(ModelParamBase* const param,
00334 const bool valueChanged,
00335 ParamClient::ChangeStatus* status)
00336 {
00337 ModelComponent::paramChanged(param, valueChanged, status);
00338
00339 if (this->started() && valueChanged)
00340 LDEBUG("online change of %s", param->getName().c_str());
00341
00342 if (param == &itsIweight) { this->envp.chan_i_weight = itsIweight.getVal(); }
00343 else if (param == &itsCweight) { this->envp.chan_c_weight = itsCweight.getVal(); }
00344 else if (param == &itsOweight) { this->envp.chan_o_weight = itsOweight.getVal(); }
00345 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00346 else if (param == &itsFweight) { this->envp.chan_f_weight = itsFweight.getVal(); }
00347 else if (param == &itsMweight) { this->envp.chan_m_weight = itsMweight.getVal(); }
00348 #endif
00349 else if (param == &itsMultithreaded)
00350 {
00351 env_set_job_server(0, 0);
00352
00353 if (itsMultithreaded.getVal())
00354 {
00355
00356 env_init_pthread_alloc();
00357
00358 itsThreadServer.reset(new WorkThreadServer("EnvVisualCortex", 12));
00359 env_set_job_server(&workthread_job_server, static_cast<void*>(itsThreadServer.get()));
00360 }
00361 else itsThreadServer.reset(0);
00362 }
00363 else if (param == &itsMaxnormType)
00364 {
00365 if (itsMaxnormType.getVal().compare("None") == 0) this->envp.maxnorm_type = ENV_VCXNORM_NONE;
00366 else if (itsMaxnormType.getVal().compare("Maxnorm") == 0) this->envp.maxnorm_type = ENV_VCXNORM_MAXNORM;
00367 else LFATAL("Invalid maxnorm type '%s' -- must be either 'Maxnorm' or 'None'", itsMaxnormType.getVal().c_str());
00368 }
00369 else if (param == &itsType)
00370 {
00371
00372 this->envp.chan_i_weight = 0;
00373 this->envp.chan_c_weight = 0;
00374 this->envp.chan_o_weight = 0;
00375 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00376 this->envp.chan_f_weight = 0;
00377 this->envp.chan_m_weight = 0;
00378 #endif
00379
00380 const std::string type = itsType.getVal();
00381 const size_t len = itsType.getVal().length();
00382
00383 for (size_t i = 0; i < len; )
00384 {
00385 const char chantype = type[i];
00386 byte* bweightptr = 0;
00387
00388 switch (chantype)
00389 {
00390 case 'I': bweightptr = &this->envp.chan_i_weight; break;
00391 case 'C': bweightptr = &this->envp.chan_c_weight; break;
00392 case 'O': bweightptr = &this->envp.chan_o_weight; break;
00393 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00394 case 'F': bweightptr = &this->envp.chan_f_weight; break;
00395 case 'M': bweightptr = &this->envp.chan_m_weight; break;
00396 #endif
00397 default: LFATAL("Invalid channel specifier '%c'", chantype);
00398 }
00399
00400 ++i;
00401
00402 if (type[i] != ':') *bweightptr = 255;
00403 else {
00404 ++i;
00405 const size_t end = type.find_first_not_of(".0123456789", i);
00406 const std::string weightstr = type.substr(i, end - i);
00407 double weight = 1.0;
00408
00409 std::stringstream s; s << weightstr; s >> weight;
00410 if (s.fail()) LFATAL("couldn't parse '%c' channel weight from '%s'", chantype, weightstr.c_str());
00411 i = end;
00412
00413 if (weight < 0.0 || weight > 1.0)
00414 LFATAL("invalid weight for channel '%c': got %s but expected a value between 0.0 and 1.0",
00415 chantype, weightstr.c_str());
00416
00417 *bweightptr = byte(weight * 255.0 + 0.5);
00418 }
00419 }
00420 }
00421 else if (param == &itsNumOrientations)
00422 {
00423 if (itsNumOrientations.getVal() > 99) *status = ParamClient::CHANGE_REJECTED;
00424 else this->envp.num_orientations = itsNumOrientations.getVal();
00425 }
00426 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00427 else if (param == &itsNumDirections)
00428 {
00429 if (itsNumDirections.getVal() > 99) *status = ParamClient::CHANGE_REJECTED;
00430 else this->envp.num_motion_directions = itsNumDirections.getVal();
00431 }
00432 else if (param == &itsMotionThresh)
00433 {
00434 this->envp.motion_thresh = itsMotionThresh.getVal();
00435 }
00436 else if (param == &itsFlickerThresh)
00437 {
00438 this->envp.flicker_thresh = itsFlickerThresh.getVal();
00439 }
00440 else if (param == &itsMultiScaleFlicker)
00441 {
00442 this->envp.multiscale_flicker = itsMultiScaleFlicker.getVal() ? 1 : 0;
00443 }
00444 #endif
00445 }
00446
00447
00448
00449
00450 EnvVisualCortex::EnvVisualCortex(OptionManager& mgr, const std::string& descrName,
00451 const std::string& tagName) :
00452 EnvVisualCortexBase(mgr, descrName, tagName)
00453 {
00454 this->chanmi = INTG32_MAX; this->chanma = INTG32_MIN;
00455 this->vcxmi = INTG32_MAX; this->vcxma = INTG32_MIN;
00456 }
00457
00458
00459 EnvVisualCortex::~EnvVisualCortex()
00460 { }
00461
00462
00463 void EnvVisualCortex::input(const Image<PixRGB<byte> >& rgbin)
00464 {
00465 struct env_image ivcout = env_img_initializer;
00466 struct env_image intens = env_img_initializer;
00467 struct env_image color = env_img_initializer;
00468 struct env_image ori = env_img_initializer;
00469 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00470 struct env_image flicker = env_img_initializer;
00471 struct env_image motion = env_img_initializer;
00472 #endif
00473
00474 ++this->framenum;
00475
00476 struct env_dims indims = { rgbin.getWidth(), rgbin.getHeight() };
00477
00478 npixels = indims.w * indims.h;
00479
00480 const struct env_rgb_pixel* src = (const struct env_rgb_pixel*) rgbin.getArrayPtr();
00481
00482 const struct env_rgb_pixel* src2 = (const struct env_rgb_pixel*)
00483 (itsColorSmoothing.getVal() == true && itsPrevRgb.initialized() ? itsPrevRgb.getArrayPtr() : 0);
00484
00485 env_mt_visual_cortex_input(itsMultithreaded.getVal() ? 1 : 0,
00486 &this->ivc, &this->envp,
00487 "visualcortex",
00488 src, src2,
00489 indims,
00490 0,
00491 0,
00492 &ivcout,
00493 &intens, &color, &ori
00494 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00495 , &flicker, &motion
00496 #endif
00497 );
00498
00499 env_merge_range(&ivcout, &vcxmi, &vcxma);
00500 env_rescale_range_inplace(&ivcout, vcxmi, vcxma);
00501
00502 env_visual_cortex_merge_ranges(&intens, &color, &ori,
00503 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00504 &flicker, &motion,
00505 #endif
00506 &chanmi, &chanma);
00507
00508 env_rescale_range_inplace(&intens, chanmi, chanma);
00509 env_rescale_range_inplace(&color, chanmi, chanma);
00510 env_rescale_range_inplace(&ori, chanmi, chanma);
00511 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00512 env_rescale_range_inplace(&flicker, chanmi, chanma);
00513 env_rescale_range_inplace(&motion, chanmi, chanma);
00514 #endif
00515
00516 this->itsVCXmap = convert_gray(&ivcout, ivcout.dims);
00517
00518 this->itsImap = convert_gray(&intens, ivcout.dims);
00519 this->itsCmap = convert_gray(&color, ivcout.dims);
00520 this->itsOmap = convert_gray(&ori, ivcout.dims);
00521 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00522 this->itsFmap = convert_gray(&flicker, ivcout.dims);
00523 this->itsMmap = convert_gray(&motion, ivcout.dims);
00524 #endif
00525
00526 env_img_make_empty(&ivcout);
00527 env_img_make_empty(&intens);
00528 env_img_make_empty(&color);
00529 env_img_make_empty(&ori);
00530 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00531 env_img_make_empty(&flicker);
00532 env_img_make_empty(&motion);
00533 #endif
00534
00535 itsPrevRgb = rgbin;
00536 }
00537
00538
00539
00540
00541 EnvVisualCortexFloat::EnvVisualCortexFloat(OptionManager& mgr, const std::string& descrName,
00542 const std::string& tagName) :
00543 EnvVisualCortexBase(mgr, descrName, tagName),
00544 itsOutputFactor(&OPT_EvcOutputFactor, this)
00545 { }
00546
00547
00548 EnvVisualCortexFloat::~EnvVisualCortexFloat()
00549 { }
00550
00551
00552
00553 void EnvVisualCortexFloat::input(const Image<PixRGB<byte> >& rgbin)
00554 {
00555 struct env_image ivcout = env_img_initializer;
00556 struct env_image intens = env_img_initializer;
00557 struct env_image color = env_img_initializer;
00558 struct env_image ori = env_img_initializer;
00559 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00560 struct env_image flicker = env_img_initializer;
00561 struct env_image motion = env_img_initializer;
00562 #endif
00563
00564 ++this->framenum;
00565
00566 struct env_dims indims = { rgbin.getWidth(), rgbin.getHeight() };
00567
00568 npixels = indims.w * indims.h;
00569
00570 const struct env_rgb_pixel* src = (const struct env_rgb_pixel*) rgbin.getArrayPtr();
00571
00572 const struct env_rgb_pixel* src2 = (const struct env_rgb_pixel*)
00573 (itsColorSmoothing.getVal() == true && itsPrevRgb.initialized() ? itsPrevRgb.getArrayPtr() : 0);
00574
00575 env_mt_visual_cortex_input(itsMultithreaded.getVal() ? 1 : 0,
00576 &this->ivc, &this->envp,
00577 "visualcortex",
00578 src, src2,
00579 indims,
00580 0,
00581 0,
00582 &ivcout,
00583 &intens, &color, &ori
00584 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00585 , &flicker, &motion
00586 #endif
00587 );
00588
00589 this->itsVCXmap = convert_gray_float(&ivcout, ivcout.dims, itsOutputFactor.getVal());
00590
00591 this->itsImap = convert_gray_float(&intens, ivcout.dims, 1.0F);
00592 this->itsCmap = convert_gray_float(&color, ivcout.dims, 1.0F);
00593 this->itsOmap = convert_gray_float(&ori, ivcout.dims, 1.0F);
00594 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00595 this->itsFmap = convert_gray_float(&flicker, ivcout.dims, 1.0F);
00596 this->itsMmap = convert_gray_float(&motion, ivcout.dims, 1.0F);
00597 #endif
00598
00599 env_img_make_empty(&ivcout);
00600 env_img_make_empty(&intens);
00601 env_img_make_empty(&color);
00602 env_img_make_empty(&ori);
00603 #ifdef ENV_WITH_DYNAMIC_CHANNELS
00604 env_img_make_empty(&flicker);
00605 env_img_make_empty(&motion);
00606 #endif
00607
00608 itsPrevRgb = rgbin;
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 #endif // NEURO_ENVVISUALCORTEX_C_DEFINED