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 #include "Channels/ChannelBase.H"
00039 #include "Channels/ChannelOpts.H"
00040 #include "Component/GlobalOpts.H"
00041 #include "Component/ModelManager.H"
00042 #include "Devices/DeviceOpts.H"
00043 #include "Devices/FrameGrabberConfigurator.H"
00044 #include "Devices/VCC4.H"
00045 #include "GUI/XWinManaged.H"
00046 #include "Image/DrawOps.H"
00047 #include "Image/Image.H"
00048 #include "Image/ShapeOps.H"
00049 #include "Image/fancynorm.H"
00050 #include "Media/MediaSimEvents.H"
00051 #include "Neuro/NeuroOpts.H"
00052 #include "Neuro/NeuroSimEvents.H"
00053 #include "Neuro/SaccadeControllers.H"
00054 #include "Neuro/ShapeEstimator.H"
00055 #include "Neuro/SimulationViewerStd.H"
00056 #include "Neuro/SpatialMetrics.H"
00057 #include "Neuro/StdBrain.H"
00058 #include "Neuro/VisualCortex.H"
00059 #include "Simulation/SimEventQueueConfigurator.H"
00060 #include "Transport/FrameIstream.H"
00061 #include "Util/log.H"
00062
00063 #include <algorithm>
00064 #include <cmath>
00065 #include <iostream>
00066 #include <stdio.h>
00067
00068
00069 #define CAM_WINDOW_NAME "Saliency Calculated"
00070 #define CAM_PREV_NAME "Captured Image"
00071 #define ANG_FACTOR (180.0/Pi)
00072 #define MAXPAN ((float)100.0)
00073 #define MINPAN ((float)-100.0)
00074 #define MAXTILT ((float)30.0)
00075 #define MINTILT ((float)-30.0)
00076
00077
00078 #define TOO_MUCH_TIME SimTime::SECS(0.7)
00079
00080
00081 float sqr (float x);
00082 float randang();
00083
00084
00085 inline float randang ()
00086 {
00087 const float max_randang = 30.0;
00088 return ((float)(2.0 * rand() / RAND_MAX) - 1.0) * max_randang;
00089 }
00090
00091
00092 inline float sqr (float x)
00093 {
00094 return (x * x);
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 int main(const int argc, const char **argv)
00113 {
00114 LOG_FLAGS &= (~LOG_FULLTRACE);
00115
00116
00117 ModelManager manager("Saccade Tester");
00118
00119
00120 nub::soft_ref<SimEventQueueConfigurator>
00121 seqc(new SimEventQueueConfigurator(manager));
00122 manager.addSubComponent(seqc);
00123
00124 nub::soft_ref<FrameGrabberConfigurator>
00125 gbc(new FrameGrabberConfigurator(manager));
00126 manager.addSubComponent(gbc);
00127
00128 nub::soft_ref<VCC4> pantilt(new VCC4(manager));
00129 manager.addSubComponent(pantilt);
00130
00131 nub::soft_ref<StdBrain> brain(new StdBrain(manager));
00132 manager.addSubComponent(brain);
00133
00134 nub::ref<SpatialMetrics> metrics(new SpatialMetrics(manager));
00135 manager.addSubComponent(metrics);
00136
00137
00138
00139
00140 manager.setOptionValString(&OPT_FrameGrabberType, "V4L");
00141 manager.setOptionValString(&OPT_FrameGrabberDims, "320x240");
00142 manager.setOptionValString(&OPT_FrameGrabberChannel, "1");
00143
00144
00145 manager.setOptionValString(&OPT_OriInteraction,"SubtractMean");
00146 manager.setOptionValString(&OPT_OrientComputeType,"Steerable");
00147 manager.setOptionValString(&OPT_RawVisualCortexChans,"OIC");
00148 manager.setOptionValString(&OPT_UseRandom,"false");
00149 manager.setOptionValString(&OPT_ShapeEstimatorMode,"FeatureMap");
00150 manager.setOptionValString(&OPT_ShapeEstimatorSmoothMethod,"Chamfer");
00151 manager.setOptionValString(&OPT_IORtype,"ShapeEst");
00152 manager.setOptionValString(&OPT_SVdisplayFOA,"true");
00153 manager.setOptionValString(&OPT_SVdisplayPatch,"false");
00154 manager.setOptionValString(&OPT_SVdisplayFOALinks,"false");
00155 manager.setOptionValString(&OPT_SVdisplayAdditive,"false");
00156 manager.setOptionValString(&OPT_SVdisplayTime,"false");
00157 manager.setOptionValString(&OPT_SVdisplayBoring,"false");
00158 metrics->setFOAradius(20);
00159
00160
00161 if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1);
00162
00163
00164 nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber();
00165 if (gb.isInvalid())
00166 LFATAL("You need to select a frame grabber type via the "
00167 "--fg-type=XX command-line option for this program "
00168 "to be useful");
00169 const Dims dims = gb->peekDims();
00170 nub::soft_ref<SimEventQueue> seq = seqc->getQ();
00171
00172
00173 manager.start();
00174
00175 float hdeg = 80, wdeg = 100;;
00176 float min_dist = std::min(hdeg, wdeg) / 12;
00177 const int num_mem = 10;
00178 float mem_pan[num_mem], mem_tilt[num_mem];
00179 int mem_ptr = 0;
00180 bool mem_filled = false;
00181 bool is_in_mem;
00182 int mem_top;
00183
00184 pantilt->CameraInitialize(true);
00185 pantilt->PlainCommand(VCC4_SetZoomingWIDE);
00186
00187 XWinManaged salWin(dims*2, -1, -1, CAM_WINDOW_NAME);
00188 XWinManaged capWin(dims*2, -1, -1, CAM_PREV_NAME);
00189
00190
00191 Image<PixRGB <byte> > capImg, salImg, capImg2;
00192
00193 float campos_pan = 0.0, campos_tilt = 0.0;
00194 float oldpos_pan = 0.0, oldpos_tilt = 0.0;
00195 float newpos_pan, newpos_tilt;
00196
00197
00198 while (!salWin.pressedCloseButton() && !capWin.pressedCloseButton())
00199 {
00200
00201
00202
00203
00204 brain->reset(MC_RECURSE);
00205
00206
00207 for (int i = 0; i < 20; i++) capImg = gb->readRGB();
00208 capImg2 = capImg;
00209 drawDisk(capImg2, Point2D<int>(dims/2),
00210 3, PixRGB<byte>(255,0,0));
00211 capWin.drawImage(rescale(capImg2,dims*2));
00212 rutz::shared_ptr<SimEventInputFrame>
00213 e(new SimEventInputFrame(brain.get(), GenericFrame(capImg), 0));
00214 seq->post(e);
00215
00216
00217 seq->resetTime();
00218 while(true)
00219 {
00220 Point2D<int> winner(-1, -1);
00221 while(seq->now() < TOO_MUCH_TIME)
00222 {
00223 if (SeC<SimEventWTAwinner> e =
00224 seq->check<SimEventWTAwinner>(0))
00225 {
00226 winner = e->winner().p;
00227 break;
00228 }
00229 if (seq->evolve() == SIM_BREAK) LFATAL("BREAK");
00230 }
00231
00232
00233 if (seq->now() >= TOO_MUCH_TIME || winner.isValid() == false)
00234 {
00235 newpos_pan = oldpos_pan + randang();
00236 newpos_pan = std::max(newpos_pan, MINPAN);
00237 newpos_pan = std::min(newpos_pan, MAXPAN);
00238
00239 newpos_tilt = oldpos_tilt + randang();
00240 newpos_tilt = std::max(newpos_tilt, MINTILT);
00241 newpos_tilt = std::min(newpos_tilt, MAXTILT);
00242
00243 LINFO("Using random position.");
00244 break;
00245 }
00246
00247
00248
00249 newpos_pan = oldpos_pan + (((float)winner.i -
00250 0.5 * (float)dims.w()) /
00251 (float)dims.w() * 0.5 * wdeg);
00252
00253
00254 newpos_pan = std::max(newpos_pan, MINPAN);
00255 newpos_pan = std::min(newpos_pan, MAXPAN);
00256
00257 newpos_tilt = oldpos_tilt + ((0.5 * (float)dims.h() -
00258 (float)winner.j) /
00259 (float)dims.h() * 0.5 * hdeg);
00260
00261
00262 newpos_tilt = std::max(newpos_tilt, MINTILT);
00263 newpos_tilt = std::min(newpos_tilt, MAXTILT);
00264
00265 is_in_mem = false;
00266 mem_top = mem_filled ? num_mem : mem_ptr;
00267 for (int i = 0; i < mem_top; i++)
00268 is_in_mem |= (sqr(newpos_pan - mem_pan[i]) +
00269 sqr(newpos_tilt - mem_tilt[i]) < sqr(min_dist));
00270
00271 if (!is_in_mem) break;
00272
00273 LDEBUG("Using next cycle.");
00274 LDEBUG("newpos = %f, %f", newpos_pan, newpos_tilt);
00275 #ifdef DEBUG
00276 std::cout << "Mark 15 \n";
00277 for (int i = 0; i < mem_top; i++)
00278 LDEBUG("mempos[%i] = %f, %f",i, mem_pan[i], mem_tilt[i]);
00279 #endif
00280 }
00281
00282 campos_pan = newpos_pan;
00283 campos_tilt = newpos_tilt;
00284
00285 mem_pan [mem_ptr] = newpos_pan;
00286 mem_tilt [mem_ptr] = newpos_tilt;
00287 mem_ptr++;
00288
00289 if (mem_ptr >= num_mem)
00290 {
00291 mem_ptr = 0;
00292 mem_filled = true;
00293 }
00294
00295 LDEBUG("mem_ptr = %i",mem_ptr);
00296 LDEBUG("newpos = %i, %i",int(newpos_pan),int(newpos_tilt));
00297
00298 oldpos_pan = newpos_pan;
00299 oldpos_tilt = newpos_tilt;
00300 pantilt->gotoPosition (campos_pan, campos_tilt);
00301
00302
00303
00304
00305
00306
00307 salWin.drawImage(rescale(salImg,dims*2));
00308
00309
00310 }
00311 pantilt->PlainCommand(VCC4_GoHome);
00312 manager.stop();
00313 return 0;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322