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 IT_C_DEFINED
00039 #define IT_C_DEFINED
00040
00041 #include "Image/DrawOps.H"
00042 #include "Image/MathOps.H"
00043
00044 #include "Image/Kernels.H"
00045 #include "Image/FilterOps.H"
00046 #include "Image/Convolutions.H"
00047 #include "Image/fancynorm.H"
00048 #include "Image/Point3D.H"
00049 #include "plugins/SceneUnderstanding/IT.H"
00050 #include "Neuro/EnvVisualCortex.H"
00051 #include "GUI/DebugWin.H"
00052 #include "Util/CpuTimer.H"
00053 #include <math.h>
00054 #include <fcntl.h>
00055 #include <limits>
00056 #include <string>
00057 #include <queue>
00058
00059 const ModelOptionCateg MOC_IT = {
00060 MOC_SORTPRI_3, "IT-Related Options" };
00061
00062 const ModelOptionDef OPT_ITShowDebug =
00063 { MODOPT_ARG(bool), "ITShowDebug", &MOC_IT, OPTEXP_CORE,
00064 "Show debug img",
00065 "it-debug", '\0', "<true|false>", "false" };
00066
00067
00068 IT::IT(OptionManager& mgr, const std::string& descrName,
00069 const std::string& tagName) :
00070 SimModule(mgr, descrName, tagName),
00071 SIMCALLBACK_INIT(SimEventV4Output),
00072 SIMCALLBACK_INIT(SimEventSaveOutput),
00073 itsShowDebug(&OPT_ITShowDebug, this),
00074 itsObjectsDist(370.00)
00075 {
00076
00077
00078 itsCamera = Camera(Point3D<float>(0,0,0.0),
00079 Point3D<float>(0, 0,0),
00080 450,
00081 320,
00082 240);
00083
00084 itsHashedGeonsState.set_empty_key(-1);
00085
00086 itsObjects.resize(4);
00087
00088
00089
00090
00091 Object houseObject;
00092 V4::GeonState geon;
00093 geon.pos = Point3D<float>(0, -15, 0);
00094 geon.rot = 0.75*M_PI;
00095 geon.geonType = V4::TRIANGLE;
00096 geon.posSigma = Point3D<float>(2, 2, 2);
00097 geon.rotSigma = 10*M_PI/180;
00098 houseObject.geons.push_back(geon);
00099
00100 geon.pos = Point3D<float>(0, 15, 0);
00101 geon.rot = 0;
00102 geon.geonType = V4::SQUARE;
00103 geon.posSigma = Point3D<float>(2, 2, 2);
00104 geon.rotSigma = 10*M_PI/180;
00105 houseObject.geons.push_back(geon);
00106 houseObject.objectType = HOUSE;
00107 itsObjects[HOUSE] = houseObject;
00108
00109
00110 Object womanObject;
00111
00112 geon.pos = Point3D<float>(0, -15, 0);
00113 geon.rot = 0;
00114 geon.geonType = V4::CIRCLE;
00115 geon.posSigma = Point3D<float>(2, 2, 2);
00116 geon.rotSigma = 10*M_PI/180;
00117 womanObject.geons.push_back(geon);
00118
00119 geon.pos = Point3D<float>(0, 15, 0);
00120 geon.rot = 0.75*M_PI;
00121 geon.geonType = V4::TRIANGLE;
00122 geon.posSigma = Point3D<float>(2, 2, 2);
00123 geon.rotSigma = 10*M_PI/180;
00124 womanObject.geons.push_back(geon);
00125 womanObject.objectType = WOMAN;
00126 itsObjects[WOMAN] = womanObject;
00127
00128
00129
00130 Object hatObject;
00131 geon.pos = Point3D<float>(0, -15, 0);
00132 geon.rot = 0.75*M_PI;
00133 geon.geonType = V4::TRIANGLE;
00134 geon.posSigma = Point3D<float>(2, 2, 2);
00135 geon.rotSigma = 10*M_PI/180;
00136 hatObject.geons.push_back(geon);
00137
00138 geon.pos = Point3D<float>(0, 15, 0);
00139 geon.rot = 0;
00140 geon.geonType = V4::CIRCLE;
00141 geon.posSigma = Point3D<float>(2, 2, 2);
00142 geon.rotSigma = 10*M_PI/180;
00143 hatObject.geons.push_back(geon);
00144 hatObject.objectType = HAT;
00145 itsObjects[HAT] = hatObject;
00146
00147
00148 Object manObject;
00149
00150 geon.pos = Point3D<float>(0, -15, 0);
00151 geon.rot = 0;
00152 geon.geonType = V4::CIRCLE;
00153 geon.posSigma = Point3D<float>(2, 2, 2);
00154 geon.rotSigma = 10*M_PI/180;
00155 manObject.geons.push_back(geon);
00156
00157 geon.pos = Point3D<float>(0, 15, 0);
00158 geon.rot = 0;
00159 geon.geonType = V4::SQUARE;
00160 geon.posSigma = Point3D<float>(2, 2, 2);
00161 geon.rotSigma = 10*M_PI/180;
00162 manObject.geons.push_back(geon);
00163 manObject.objectType = MAN;
00164 itsObjects[MAN] = manObject;
00165
00166 buildRTables();
00167
00168 itsObjectsParticles.resize(1000);
00169 for(uint i=0; i<itsObjectsParticles.size(); i++)
00170 {
00171 itsObjectsParticles[i].objectType = HOUSE;
00172 itsObjectsParticles[i].weight = 1.0/100.0;
00173 }
00174
00175
00176
00177 }
00178
00179
00180 IT::~IT()
00181 {
00182
00183 }
00184
00185
00186 void IT::buildRTables()
00187 {
00188
00189 for(uint objId=0; objId<itsObjects.size(); objId++)
00190 {
00191 Point3D<float> pos(0,0,itsObjectsDist);
00192 float rot = 0;
00193
00194 for(uint gid = 0; gid < itsObjects[objId].geons.size(); gid++)
00195 {
00196 V4::GeonState geonState = itsObjects[objId].geons[gid];
00197
00198 geonState.rot += rot;
00199 float x = geonState.pos.x;
00200 float y = geonState.pos.y;
00201 float z = geonState.pos.z;
00202 geonState.pos.x = (cos(rot)*x - sin(rot)*y) + pos.x;
00203 geonState.pos.y = (sin(rot)*x + cos(rot)*y) + pos.y;
00204 geonState.pos.z = z + pos.z;
00205
00206 Point2D<int> loc = (Point2D<int>)itsCamera.project(geonState.pos);
00207
00208 RTableEntry rTableEntry;
00209 rTableEntry.geonType = geonState.geonType;
00210 rTableEntry.loc.i = loc.i - 320/2;
00211 rTableEntry.loc.j = loc.j - 240/2;
00212 rTableEntry.rot = geonState.rot;
00213
00214 itsObjects[objId].rTable.push_back(rTableEntry);
00215 }
00216
00217
00218
00219 }
00220 }
00221
00222
00223 void IT::init(Dims numCells)
00224 {
00225
00226 }
00227
00228
00229 void IT::onSimEventV4Output(SimEventQueue& q,
00230 rutz::shared_ptr<SimEventV4Output>& e)
00231 {
00232 std::vector<V4::GeonState> geonsState = e->getCells();
00233
00234
00235 itsHashedGeonsState.clear();
00236
00237 itsGeonsState.clear();
00238 for(uint i=0; i<geonsState.size(); i++)
00239 {
00240 if (geonsState[i].prob > 0)
00241 {
00242 itsGeonsState.push_back(geonsState[i]);
00243
00244 int key = i;
00245 itsHashedGeonsState[key] = geonsState[i];
00246 }
00247 }
00248
00249 evolve();
00250
00251
00252
00253
00254 }
00255
00256
00257 void IT::onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00258 {
00259 if (itsShowDebug.getVal())
00260 {
00261
00262
00263 nub::ref<FrameOstream> ofs =
00264 dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00265 Layout<PixRGB<byte> > disp = getDebugImage();
00266 ofs->writeRgbLayout(disp, "IT", FrameInfo("IT", SRC_POS));
00267 }
00268 }
00269
00270
00271 void IT::setInput(const std::vector<V4::GeonState> &geonsState)
00272 {
00273 itsHashedGeonsState.clear();
00274 for(uint i=0; i<geonsState.size(); i++)
00275 {
00276
00277 int key = i;
00278 itsHashedGeonsState[key] = geonsState[i];
00279 }
00280
00281 evolve();
00282 }
00283
00284
00285 void IT::showObject(Image<PixRGB<byte> > &img, Object& object, Point3D<float>& pos, float rot)
00286 {
00287
00288 PixRGB<byte> col;
00289 switch (object.objectType)
00290 {
00291 case HOUSE: col = PixRGB<byte>(255,0,0); break;
00292 case WOMAN: col = PixRGB<byte>(0,255,0); break;
00293 case HAT: col = PixRGB<byte>(0,255,255); break;
00294 case MAN: col = PixRGB<byte>(0,0,255); break;
00295 default: break;
00296 }
00297
00298 for(uint geonId=0; geonId<object.geons.size(); geonId++)
00299 {
00300
00301 V4::GeonState geonState = object.geons[geonId];
00302
00303 geonState.rot += rot;
00304 float x = geonState.pos.x;
00305 float y = geonState.pos.y;
00306 float z = geonState.pos.z;
00307 geonState.pos.x = (cos(rot)*x - sin(rot)*y) + pos.x;
00308 geonState.pos.y = (sin(rot)*x + cos(rot)*y) + pos.y;
00309 geonState.pos.z = z + pos.z;
00310
00311 Point2D<int> loc = (Point2D<int>)itsCamera.project(geonState.pos);
00312
00313 switch(geonState.geonType)
00314 {
00315 case V4::SQUARE:
00316 drawRectOR(img, Rectangle(loc - Point2D<int>(20,20), Dims((int)40,(int)40)),
00317 col, 1, geonState.rot);
00318 break;
00319 case V4::CIRCLE:
00320 if (object.objectType != HAT)
00321 drawCircle(img, loc, 20, col);
00322 break;
00323 case V4::TRIANGLE:
00324 {
00325 std::vector<Point3D<float> > outline;
00326 outline.push_back(Point3D<float>(0.0,0, 0.0));
00327 outline.push_back(Point3D<float>(0.0,-40.0, 0.0));
00328 outline.push_back(Point3D<float>(40.0, 0.0, 0.0));
00329
00330
00331 float centerX = 0, centerY = 0, centerZ = 0;
00332 for(uint i=0; i<outline.size(); i++)
00333 {
00334 centerX += outline[i].x;
00335 centerY += outline[i].y;
00336 centerZ += outline[i].z;
00337 }
00338 centerX /= outline.size();
00339 centerY /= outline.size();
00340 centerZ /= outline.size();
00341
00342 for(uint i=0; i<outline.size(); i++)
00343 outline[i] -= Point3D<float>(centerX, centerY, centerZ);
00344
00345 for(uint i=0; i<outline.size(); i++)
00346 {
00347 float x = outline[i].x;
00348 float y = outline[i].y;
00349 float z = outline[i].z;
00350 outline[i].x = (cos(geonState.rot)*x - sin(geonState.rot)*y) + geonState.pos.x;
00351 outline[i].y = (sin(geonState.rot)*x + cos(geonState.rot)*y) + geonState.pos.y;
00352 outline[i].z = z + geonState.pos.z;
00353 }
00354
00355
00356 std::vector<Point2D<int> > points;
00357
00358 for(uint i=0; i<outline.size(); i++)
00359 {
00360 Point2D<float> loc = itsCamera.project(outline[i]);
00361 points.push_back(Point2D<int>(loc));
00362 }
00363
00364 for(uint i=0; i<points.size(); i++)
00365 drawLine(img, points[i], points[(i+1)%points.size()], col, 1);
00366
00367 }
00368 break;
00369 }
00370 }
00371
00372 }
00373
00374
00375 void IT::evolve()
00376 {
00377
00378
00379
00380 proposeParticles(itsObjectsParticles, 0.0F);
00381
00382
00383 evaluateObjectParticles(itsObjectsParticles);
00384
00385 }
00386
00387
00388 float IT::evaluateObjectParticles(std::vector<ObjectState>& objectParticles)
00389 {
00390
00391 for(uint p=0; p<objectParticles.size(); p++)
00392 getObjectLikelihood(objectParticles[p]);
00393
00394
00395 double sum = 0;
00396 double Neff = 0;
00397 for(uint i=0; i<objectParticles.size(); i++)
00398 sum += objectParticles[i].prob;
00399
00400 for(uint i=0; i<objectParticles.size(); i++)
00401 {
00402 objectParticles[i].weight = objectParticles[i].prob/sum;
00403 Neff += squareOf(objectParticles[i].weight);
00404 }
00405
00406 Neff = 1/Neff;
00407
00408
00409 return Neff;
00410
00411 }
00412
00413 void IT::GHT(std::vector<GHTAcc>& accRet, OBJECT_TYPE objectType)
00414 {
00415 ImageSet<float> acc(360, Dims(320,240), ZEROS);
00416
00417 CpuTimer timer;
00418 timer.reset();
00419
00420
00421
00422
00423
00424
00425
00426 int angIdx = 0;
00427 voteForFeature(acc[angIdx], angIdx, itsObjects[objectType].rTable);
00428
00429 timer.mark();
00430 LINFO("Total time %0.2f sec", timer.real_secs());
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 for(uint rot=0; rot<acc.size(); rot++)
00446 for(int y=0; y<acc[rot].getHeight(); y++)
00447 for(int x=0; x<acc[rot].getWidth(); x++)
00448 if (acc[rot].getVal(x,y) > 0)
00449 {
00450 GHTAcc ghtAcc;
00451 ghtAcc.objectType = objectType;
00452 ghtAcc.pos = Point2D<int>(x,y);
00453 ghtAcc.ang = rot;
00454 ghtAcc.scale = -1;
00455 ghtAcc.sum = acc[rot].getVal(x,y);
00456 accRet.push_back(ghtAcc);
00457 }
00458
00459 }
00460
00461 void IT::voteForFeature(Image<float>& acc, int angIdx, std::vector<RTableEntry>& rTable)
00462 {
00463
00464 for(uint g=0; g < itsGeonsState.size(); g++)
00465 {
00466 V4::GeonState geonState = itsGeonsState[g];
00467 if (geonState.prob > 0)
00468 {
00469 Point2D<int> loc = (Point2D<int>)itsCamera.project(geonState.pos);
00470
00471
00472 for(uint rIdx = 0; rIdx < rTable.size(); rIdx++)
00473 {
00474 if (rTable[rIdx].geonType == geonState.geonType)
00475 {
00476 float ang = angIdx * M_PI/180;
00477
00478 float featureAng = rTable[rIdx].rot + ang;
00479 if (featureAng < 0)
00480 featureAng += M_PI*2;
00481 if (featureAng > M_PI*2)
00482 featureAng -= M_PI*2;
00483
00484 float diffRot = acos(cos(geonState.rot - featureAng));
00485
00486 float stddevRot = 1.5;
00487 int sizeRot = int(ceil(stddevRot * sqrt(-2.0F * log(exp(-5.0F)))));
00488
00489 if (fabs(diffRot) < sizeRot*M_PI/180)
00490 {
00491 float rRot = exp(-((diffRot*diffRot)/(stddevRot*stddevRot)));
00492
00493
00494
00495 float stddevX = 1.5;
00496 float stddevY = 1.5;
00497 int sizeX = int(ceil(stddevX * sqrt(-2.0F * log(exp(-5.0F)))));
00498 int sizeY = int(ceil(stddevY * sqrt(-2.0F * log(exp(-5.0F)))));
00499
00500 for(int y=loc.j-sizeY; y<loc.j+sizeY; y++)
00501 {
00502 float diffY = y-loc.j;
00503 float ry = exp(-((diffY*diffY)/(stddevY*stddevY)));
00504 for(int x=loc.i-sizeX; x<loc.i+sizeX; x++)
00505 {
00506 float diffX = x-loc.i;
00507 float rx = exp(-((diffX*diffX)/(stddevX*stddevX)));
00508
00509 float weight = rRot*rx*ry;
00510
00511 int a0 = x - int(rTable[rIdx].loc.i*cos(ang) - rTable[rIdx].loc.j*sin(ang));
00512 int b0 = y - int(rTable[rIdx].loc.i*sin(ang) + rTable[rIdx].loc.j*cos(ang));
00513 if (acc.coordsOk(a0, b0))
00514 {
00515 float val = acc.getVal(a0, b0);
00516 val += weight;
00517 acc.setVal(a0, b0, val);
00518 }
00519 }
00520 }
00521 }
00522 }
00523 }
00524 }
00525 }
00526 }
00527
00528 void IT::normalizeAcc(std::vector<GHTAcc>& acc)
00529 {
00530
00531 double sum = 0;
00532 for(uint i=0; i<acc.size(); i++)
00533 sum += acc[i].sum;
00534
00535 for(uint i=0; i<acc.size(); i++)
00536 acc[i].sum /= sum;
00537 }
00538
00539
00540 Image<float> IT::showParticles(const std::vector<ObjectState>& objectParticles)
00541 {
00542 Image<float> probImg(320,240, ZEROS);
00543
00544 for(uint i=0; i<objectParticles.size(); i++)
00545 {
00546 Point2D<int> loc = (Point2D<int>)itsCamera.project(objectParticles[i].pos);
00547 if (probImg.coordsOk(loc))
00548 probImg.setVal(loc, probImg.getVal(loc) + objectParticles[i].weight);
00549 }
00550 inplaceNormalize(probImg, 0.0F, 255.0F);
00551
00552 return probImg;
00553
00554 }
00555
00556
00557 void IT::proposeParticles(std::vector<ObjectState>& objectParticles, const double Neff)
00558 {
00559 LINFO("Propose Particles");
00560
00561 float probThresh = 1.0e-2;
00562
00563
00564 uint objectsAboveProb = 0;
00565
00566 for(uint i=0; i<objectParticles.size(); i++)
00567 {
00568 if (objectParticles[i].prob > probThresh)
00569 {
00570 objectParticles[i].pos.x += randomDoubleFromNormal(1.0);
00571 objectParticles[i].pos.y += randomDoubleFromNormal(1.0);
00572 objectParticles[i].pos.z = itsObjectsDist + randomDoubleFromNormal(0.05);
00573 objectParticles[i].rot += randomDoubleFromNormal(1.0)*M_PI/180;
00574 objectParticles[i].weight = 1.0/(float)objectParticles.size();
00575 objectsAboveProb++;
00576 }
00577 }
00578
00579
00580
00581
00582 if (objectsAboveProb < objectParticles.size())
00583 {
00584
00585 LINFO("GHT sampleing");
00586 std::vector<GHTAcc> acc;
00587 GHT(acc, HOUSE);
00588 GHT(acc, WOMAN);
00589 GHT(acc, HAT);
00590 GHT(acc, MAN);
00591
00592 LINFO("GHT Done ");
00593
00594 if (acc.size() == 0)
00595 return;
00596 normalizeAcc(acc);
00597
00598 std::priority_queue <GHTAcc> pAcc;
00599 for(uint i=0; i<acc.size(); i++)
00600 pAcc.push(acc[i]);
00601
00602
00603 for(uint i=0; i<objectParticles.size(); i++)
00604 {
00605 if (objectParticles[i].prob <= probThresh)
00606 {
00607
00608 if (pAcc.empty())
00609 break;
00610 GHTAcc p = pAcc.top(); pAcc.pop();
00611
00612 Point3D<float> iPoint = itsCamera.inverseProjection(Point2D<float>(p.pos), itsObjectsDist);
00613 objectParticles[i].pos.x = iPoint.x + randomDoubleFromNormal(1);
00614 objectParticles[i].pos.y = iPoint.y + randomDoubleFromNormal(1);
00615 objectParticles[i].pos.z = itsObjectsDist + randomDoubleFromNormal(0.05);
00616 objectParticles[i].rot = (p.ang + randomDoubleFromNormal(1))*M_PI/180;
00617 objectParticles[i].objectType = p.objectType;
00618 objectParticles[i].weight = 1.0/(float)objectParticles.size();
00619 objectParticles[i].prob = 1.0e-50;
00620 }
00621 }
00622 }
00623 }
00624
00625
00626 void IT::resampleParticles(std::vector<ObjectState>& objectParticles)
00627 {
00628 LINFO("Resample");
00629
00630 std::vector<ObjectState> newParticles;
00631
00632
00633 std::vector<double> CDF;
00634 CDF.resize(objectParticles.size());
00635
00636 CDF.at(0) = objectParticles.at(0).weight;
00637 for(uint i=1; i<CDF.size(); i++)
00638 CDF.at(i) = CDF.at(i-1) + objectParticles.at(i).weight;
00639
00640 uint i = 0;
00641 double u = randomDouble()* 1.0/double(objectParticles.size());
00642
00643 for(uint j=0; j < objectParticles.size(); j++)
00644 {
00645 while(u > CDF.at(i))
00646 i++;
00647
00648 ObjectState p = objectParticles.at(i);
00649 p.weight = 1.0/double(objectParticles.size());
00650 newParticles.push_back(p);
00651
00652 u += 1.0/double(objectParticles.size());
00653 }
00654
00655 objectParticles = newParticles;
00656
00657 }
00658
00659
00660 void IT::getObjectLikelihood(ObjectState& objectState)
00661 {
00662
00663 Object object = itsObjects[objectState.objectType];
00664 Point2D<int> loc = (Point2D<int>)itsCamera.project(objectState.pos);
00665 float rot = objectState.rot + M_PI;
00666
00667
00668 double totalProb = 1;
00669
00670 for(uint rIdx=0; rIdx<object.rTable.size(); rIdx++)
00671 {
00672 float ang = rot;
00673 float a0 = loc.i - (object.rTable[rIdx].loc.i*cos(ang) - object.rTable[rIdx].loc.j*sin(ang));
00674 float b0 = loc.j - (object.rTable[rIdx].loc.i*sin(ang) + object.rTable[rIdx].loc.j*cos(ang));
00675
00676
00677 V4::GeonState geonState;
00678 geonState.pos = itsCamera.inverseProjection(Point2D<float>(a0,b0), itsObjectsDist);
00679 geonState.rot = rot + object.rTable[rIdx].rot + M_PI;
00680 geonState.geonType = object.rTable[rIdx].geonType;
00681 geonState.prob = -1;
00682
00683 while (geonState.rot < 0)
00684 geonState.rot += M_PI*2;
00685 while(geonState.rot > M_PI*2)
00686 geonState.rot -= M_PI*2;
00687
00688
00689
00690 int nearPart = 0;
00691 float partDist = 1.0e100;
00692 for(uint i=0; i<itsGeonsState.size(); i++)
00693 {
00694 if (itsGeonsState[i].prob > 0)
00695 {
00696 float distance = geonState.distance(itsGeonsState[i]);
00697 if (distance < partDist)
00698 {
00699 partDist = distance;
00700 nearPart = i;
00701 }
00702 }
00703 }
00704
00705 float sig = 0.75F;
00706 float prob = (1.0F/(sig*sqrt(2*M_PI))*exp(-0.5*squareOf(partDist)/squareOf(sig)));
00707
00708 totalProb *= prob;
00709 }
00710
00711
00712
00713 objectState.prob = totalProb;
00714
00715
00716 }
00717
00718 void IT::fixAngle(float& ang)
00719 {
00720 if (ang > M_PI)
00721 ang -= 2*M_PI;
00722
00723 if (ang < M_PI)
00724 ang += 2*M_PI;
00725 }
00726
00727
00728
00729 V4::GeonState IT::findNearestGeon(const V4::GeonState& geonState)
00730 {
00731
00732 V4::GeonState nearestGeon;
00733 nearestGeon.prob = -1;
00734 float minDistance = 1.0e100;
00735
00736 dense_hash_map<int, V4::GeonState>::const_iterator iter;
00737 for(iter = itsHashedGeonsState.begin(); iter != itsHashedGeonsState.end(); iter++)
00738 {
00739 if (geonState.geonType == iter->second.geonType && iter->second.prob > 0.5)
00740 {
00741
00742
00743 float dist = getGeonDistance(geonState, iter->second);
00744 if (dist < minDistance)
00745 {
00746 minDistance = dist;
00747 nearestGeon = iter->second;
00748 }
00749 }
00750 }
00751
00752 return nearestGeon;
00753 }
00754
00755
00756 double IT::getGeonDistance(const V4::GeonState& g1, const V4::GeonState& g2)
00757 {
00758
00759 double posDist = g1.pos.squdist(g2.pos);
00760 double rotDist = 0;
00761
00762 return sqrt(posDist + rotDist);
00763
00764 }
00765
00766
00767 Layout<PixRGB<byte> > IT::getDebugImage()
00768 {
00769 Layout<PixRGB<byte> > outDisp;
00770
00771
00772 Image<float> perc(320,240, ZEROS);
00773
00774 Image<PixRGB<byte> > objectDisp = toRGB(Image<byte>(perc));
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 for(uint obj = 0; obj < itsObjects.size(); obj++)
00805 {
00806 int maxObj = -1;
00807 float max = 0;
00808
00809 for(uint i=0; i<itsObjectsParticles.size(); i++)
00810 {
00811 if (itsObjectsParticles[i].weight > 0 && itsObjectsParticles[i].objectType == itsObjects[obj].objectType)
00812 {
00813 if (itsObjectsParticles[i].weight > max)
00814 {
00815 max = itsObjectsParticles[i].weight;
00816 maxObj = i;
00817 }
00818 }
00819 }
00820
00821
00822 if (maxObj != -1)
00823 {
00824 Object object=itsObjects[itsObjectsParticles[maxObj].objectType];
00825 ObjectState objectState = itsObjectsParticles[maxObj];
00826 showObject(objectDisp, object, objectState.pos, objectState.rot);
00827
00828 Point2D<int> textLoc = (Point2D<int>)itsCamera.project(objectState.pos);
00829 textLoc.i -= 10;
00830
00831 char msg[255];
00832 msg[0] = 0;
00833 switch (itsObjectsParticles[maxObj].objectType)
00834 {
00835 case HOUSE: sprintf(msg, "HOUSE"); break;
00836 case WOMAN: sprintf(msg, "WOMAN"); break;
00837 case HAT: sprintf(msg, "HAT"); textLoc.j -= 20; break;
00838 case MAN: sprintf(msg, "MAN"); break;
00839 default:
00840 break;
00841 }
00842 writeText(objectDisp, textLoc, msg, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0));
00843
00844 }
00845
00846 }
00847
00848
00849 Image<float> particles = showParticles(itsObjectsParticles);
00850
00851 char msg[255];
00852 sprintf(msg, "IT");
00853 writeText(objectDisp, Point2D<int>(0,0), msg, PixRGB<byte>(255,255,255), PixRGB<byte>(0,0,0));
00854
00855 outDisp = hcat(objectDisp, toRGB(Image<byte>(particles)));
00856
00857 return outDisp;
00858
00859 }
00860
00861
00862
00863
00864
00865
00866
00867 #endif
00868