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 
00039 #ifndef V1_C_DEFINED
00040 #define V1_C_DEFINED
00041 
00042 #include "plugins/SceneUnderstanding/V1.H"
00043 
00044 #include "Image/DrawOps.H"
00045 #include "Image/MathOps.H"
00046 
00047 #include "Image/Kernels.H"
00048 #include "Image/FilterOps.H"
00049 #include "Image/Convolutions.H"
00050 #include "Image/fancynorm.H"
00051 #include "Image/Point3D.H"
00052 #include "Simulation/SimEventQueue.H"
00053 #include "Neuro/EnvVisualCortex.H"
00054 #include "GUI/DebugWin.H"
00055 #include <math.h>
00056 #include <fcntl.h>
00057 #include <limits>
00058 #include <string>
00059 
00060 const ModelOptionCateg MOC_V1 = {
00061   MOC_SORTPRI_3,   "V1-Related Options" };
00062 
00063 
00064 const ModelOptionDef OPT_V1ShowDebug =
00065   { MODOPT_ARG(bool), "V1ShowDebug", &MOC_V1, OPTEXP_CORE,
00066     "Show debug img",
00067     "v1-debug", '\0', "<true|false>", "false" };
00068 
00069 
00070 
00071 SIMMODULEINSTFUNC(V1);
00072 
00073 
00074 V1::V1(OptionManager& mgr, const std::string& descrName,
00075     const std::string& tagName) :
00076   SimModule(mgr, descrName, tagName),
00077   SIMCALLBACK_INIT(SimEventLGNOutput),
00078   SIMCALLBACK_INIT(SimEventV1Bias),
00079   SIMCALLBACK_INIT(SimEventSaveOutput),
00080   SIMCALLBACK_INIT(SimEventUserInput),
00081   itsShowDebug(&OPT_V1ShowDebug, this),
00082   itsThreshold(0.10),
00083   itsBiasThreshold(0.05),
00084   itsAngBias(0)
00085 
00086 {
00087   itsAttenLoc.i = -1;
00088   itsAttenLoc.j = -1;
00089 
00090   
00091   
00092   
00093   
00094   
00095 
00096   itsWinSize = Dims(320,240);
00097 
00098 
00099 
00100 }
00101 
00102 
00103 V1::~V1()
00104 {
00105 
00106 }
00107 
00108 
00109 void V1::onSimEventLGNOutput(SimEventQueue& q,
00110                                   rutz::shared_ptr<SimEventLGNOutput>& e)
00111 {
00112   itsTimer.reset();
00113   itsLGNData = e->getCells();
00114 
00115   
00116   
00117   
00118   
00119   
00120   
00121 
00122   evolve(q);
00123 
00124   
00125 
00126 }
00127 
00128 
00129 void V1::onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00130 {
00131   if (itsShowDebug.getVal())
00132     {
00133       
00134       
00135       nub::ref<FrameOstream> ofs =
00136         dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00137       Layout<PixRGB<byte> > disp = getDebugImage();
00138       ofs->writeRgbLayout(disp, "V1", FrameInfo("V1", SRC_POS));
00139     }
00140 }
00141 
00142 
00143 void V1::setBias(const Image<float> &biasImg)
00144 {
00145 
00146 }
00147 
00148 
00149 void V1::onSimEventV1Bias(SimEventQueue& q,
00150                                   rutz::shared_ptr<SimEventV1Bias>& e)
00151 {
00152   itsSpatialBias = e->getSpatialBias();
00153   itsTimer.mark();
00154   printf("Total time %0.2f sec\n", itsTimer.real_secs());
00155   fflush(stdout);
00156 
00157   evolve(q);
00158 
00159   
00160   
00161   
00162   
00163   
00164 }
00165 
00166 void V1::onSimEventUserInput(SimEventQueue& q, rutz::shared_ptr<SimEventUserInput>& e)
00167 {
00168   LINFO("Got event %s %ix%i key=%i",
00169       e->getWinName(),
00170       e->getMouseClick().i,
00171       e->getMouseClick().j,
00172       e->getKey());
00173 
00174 
00175   if (strcmp(e->getWinName(), "V1"))
00176     return;
00177 
00178   switch(e->getKey())
00179   {
00180     case 10: 
00181       itsThreshold += 0.01;
00182       if (itsThreshold > 1) itsThreshold = 1;
00183       break;
00184     case 24: 
00185       itsThreshold -= 0.01;
00186       if (itsThreshold < 0) itsThreshold = 0;
00187       break;
00188     case 11: 
00189       itsBiasThreshold += 0.01;
00190       if (itsBiasThreshold > 1) itsBiasThreshold = 1;
00191       break;
00192     case 25: 
00193       itsBiasThreshold -= 0.01;
00194       if (itsBiasThreshold < 0) itsBiasThreshold = 0;
00195       break;
00196     default:
00197       break;
00198   }
00199 
00200   
00201   if (e->getMouseClick().isValid())
00202   {
00203     LINFO("Set spatial bias");
00204     itsAttenLoc = e->getMouseClick();
00205     
00206     
00207     
00208   }
00209 
00210   evolve(q);
00211 
00212 }
00213 
00214 
00215 
00216 void V1::evolve(SimEventQueue& q)
00217 {
00218   
00219  
00220 
00221     evolveTensor();
00222     
00223     
00224     
00225 
00226     q.post(rutz::make_shared(new SimEventV1Output(this, itsEdgesState)));
00227 }
00228 
00229 void V1::evolveTensor()
00230 {
00231   Image<float> d1;
00232   Image<float> d2;
00233   Image<float> d3;
00234 
00235   if (itsAttenLoc.isValid())
00236   {
00237     d1 = crop(itsLGNData[0], itsAttenLoc, itsWinSize);
00238     d2 = crop(itsLGNData[1], itsAttenLoc, itsWinSize);
00239     d3 = crop(itsLGNData[2], itsAttenLoc, itsWinSize);
00240   } else {
00241     d1 = itsLGNData[0];
00242     d2 = itsLGNData[1];
00243     d3 = itsLGNData[2];
00244   }
00245 
00246 
00247   itsInput = d1;
00248 
00249 
00250   itsEdgesState.lumTensorField = getTensor(d1,3);
00251   itsEdgesState.rgTensorField  = getTensor(d2,3);
00252   itsEdgesState.byTensorField  = getTensor(d3,3);
00253 
00254   
00255   nonMaxSurp(itsEdgesState.lumTensorField); 
00256   nonMaxSurp(itsEdgesState.rgTensorField);
00257   nonMaxSurp(itsEdgesState.byTensorField);
00258 
00259 
00260   LINFO("Bias size %i", (int)itsSpatialBias.size());
00261 
00262 
00263   applyThreshold(itsEdgesState.lumTensorField, itsSpatialBias);
00264   applyThreshold(itsEdgesState.rgTensorField, itsSpatialBias);
00265   applyThreshold(itsEdgesState.byTensorField, itsSpatialBias);
00266 
00267 }
00268 
00269 void V1::applyThreshold(TensorField& tensorField, std::vector<SpatialBias>& spatialBias)
00270 {
00271   
00272   Image<float> mag = getTensorMag(tensorField);
00273   float min, max;
00274   getMinMax(mag, min,max);
00275 
00276   for(int y=0; y<mag.getHeight(); y++)
00277     for(int x=0; x<mag.getWidth(); x++)
00278     {
00279       bool biased = false;
00280 
00281       for(uint i=0;  i<spatialBias.size(); i++)
00282       {
00283         if (spatialBias[i].contains(x,y))
00284         {
00285           if (mag.getVal(x,y) < max*spatialBias[i].threshold)
00286             tensorField.setVal(x,y,0);
00287           biased = true;
00288         }
00289       }
00290 
00291       if (!biased)
00292       {
00293         if (mag.getVal(x,y) < max*itsThreshold)
00294           tensorField.setVal(x,y,0);
00295       }
00296 
00297     }
00298 }
00299 
00300 
00301 
00302 
00303 
00304 
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 
00355 
00356 
00357 
00358 
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 Layout<PixRGB<byte> > V1::getDebugImage()
00440 {
00441   Layout<PixRGB<byte> > outDisp;
00442 
00443   EigenSpace eigen = getTensorEigen(itsEdgesState.lumTensorField);
00444   Image<float> lumFeatures = eigen.l1-eigen.l2;
00445 
00446   eigen = getTensorEigen(itsEdgesState.rgTensorField);
00447   Image<float> rgFeatures = eigen.l1-eigen.l2;
00448 
00449   eigen = getTensorEigen(itsEdgesState.byTensorField);
00450   Image<float> byFeatures = eigen.l1-eigen.l2;
00451 
00452   inplaceNormalize(lumFeatures, 0.0F, 255.0F);
00453   inplaceNormalize(rgFeatures, 0.0F, 255.0F);
00454   inplaceNormalize(byFeatures, 0.0F, 255.0F);
00455 
00456   
00457 
00458   Image<PixRGB<byte> > attnInput = itsInput; 
00459 
00460   Image<PixRGB<byte> > input = itsLGNData[0];
00461   if (itsAttenLoc.isValid())
00462   {
00463     drawRect(input, Rectangle(itsAttenLoc, itsWinSize), PixRGB<byte>(0,255,0), 3);
00464     input = rescale(input, attnInput.getDims());
00465   }
00466 
00467   char msg[255];
00468   sprintf(msg, "T: %0.2f BT: %0.2f", itsThreshold*100, itsBiasThreshold*100);
00469   writeText(attnInput, Point2D<int>(0,0), msg,
00470       PixRGB<byte>(255,255,255),
00471       PixRGB<byte>(0,0,0));
00472 
00473   for(uint i=0; i<itsSpatialBias.size(); i++)
00474   {
00475     Rectangle rect = Rectangle::centerDims(itsSpatialBias[i].loc, itsSpatialBias[i].dims);
00476     if (attnInput.rectangleOk(rect))
00477       drawRect(attnInput,rect ,
00478           PixRGB<byte>(255,0,0));
00479   }
00480 
00481 
00482   
00483   outDisp = hcat(input, attnInput);
00484   outDisp = hcat(outDisp, toRGB(Image<byte>(lumFeatures)));
00485   outDisp = hcat(outDisp, toRGB(Image<byte>(rgFeatures)));
00486   outDisp = hcat(outDisp, toRGB(Image<byte>(byFeatures)));
00487 
00488   return outDisp;
00489 
00490 }
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 #endif
00499