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 Geons3D_C_DEFINED
00039 #define Geons3D_C_DEFINED
00040
00041 #include "plugins/SceneUnderstanding/Geons3D.H"
00042
00043 #include "Image/DrawOps.H"
00044 #include "Image/MathOps.H"
00045 #include "Image/Kernels.H"
00046 #include "Image/FilterOps.H"
00047 #include "Image/Transforms.H"
00048 #include "Image/fancynorm.H"
00049 #include "Image/Convolutions.H"
00050 #include "Image/MatrixOps.H"
00051 #include "Simulation/SimEventQueue.H"
00052 #include "GUI/DebugWin.H"
00053 #include <math.h>
00054 #include <fcntl.h>
00055 #include <limits>
00056 #include <string>
00057
00058 const ModelOptionCateg MOC_Geons3D = {
00059 MOC_SORTPRI_3, "Geons3D-Related Options" };
00060
00061
00062 const ModelOptionDef OPT_Geons3DShowDebug =
00063 { MODOPT_ARG(bool), "Geons3DShowDebug", &MOC_Geons3D, OPTEXP_CORE,
00064 "Show debug img",
00065 "geons3d-debug", '\0', "<true|false>", "false" };
00066
00067
00068 SIMMODULEINSTFUNC(Geons3D);
00069
00070
00071
00072 Geons3D::Geons3D(OptionManager& mgr, const std::string& descrName,
00073 const std::string& tagName) :
00074 SimModule(mgr, descrName, tagName),
00075 SIMCALLBACK_INIT(SimEventTwoHalfDSketchOutput),
00076 SIMCALLBACK_INIT(SimEventSaveOutput),
00077 SIMCALLBACK_INIT(SimEventUserInput),
00078 SIMCALLBACK_INIT(SimEventGeons3DPrior),
00079 itsShowDebug(&OPT_Geons3DShowDebug, this)
00080 {
00081
00082 itsViewPort = new ViewPort3D(320,240, true, false, true);
00083
00084 double trans[3][4] = {
00085 {-0.999143, -0.041185, -0.004131, -1.142130},
00086 {-0.017002, 0.499358, -0.866229, 17.284269},
00087 {0.037739, -0.865416, -0.499630, 220.977236}};
00088
00089 itsViewPort->setCamera(trans);
00090
00091
00092
00093
00094 initRandomNumbers();
00095
00096 itsLearn = true;
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 GeonState gs;
00115 gs.pos = Point3D<float>(-31,-34,0);
00116 gs.rot = Point3D<float>(10,0,0);
00117
00118 gs.superQuadric.its_a1 = 25;
00119 gs.superQuadric.its_a2 = 30;
00120 gs.superQuadric.its_a3 = 25;
00121 gs.superQuadric.its_alpha = -1;
00122 gs.superQuadric.its_n = 0.0;
00123 gs.superQuadric.its_e = 1.0;
00124 gs.superQuadric.its_u1 = -M_PI ;
00125 gs.superQuadric.its_u2 = M_PI;
00126 gs.superQuadric.its_v1 = -M_PI;
00127 gs.superQuadric.its_v2 = M_PI;
00128 gs.superQuadric.its_s1 = 0.0f;
00129 gs.superQuadric.its_t1 = 0.0f;
00130 gs.superQuadric.its_s2 = 1.0f;
00131 gs.superQuadric.its_t2 = 1.0f;
00132
00133 itsProposals.push_back(gs);
00134 }
00135
00136
00137 Geons3D::~Geons3D()
00138 {
00139 }
00140
00141
00142
00143 void Geons3D::onSimEventTwoHalfDSketchOutput(SimEventQueue& q,
00144 rutz::shared_ptr<SimEventTwoHalfDSketchOutput>& e)
00145 {
00146
00147
00148 if (SeC<SimEventLGNOutput> lgn = q.check<SimEventLGNOutput>(this))
00149 {
00150 rutz::shared_ptr<GenericFrame::MetaData> metaData = lgn->getMetaData();
00151 if (metaData.get() != 0) {
00152 itsObjectsData.dyn_cast_from(metaData);
00153 }
00154 itsLGNInput = lgn->getCells();
00155 }
00156
00157
00158 if (SeC<SimEventSMapOutput> smap = q.check<SimEventSMapOutput>(this))
00159 itsSMap = smap->getSMap();
00160
00161 itsSurfaces = e->getSurfaces();
00162
00163 evolve(q);
00164
00165 }
00166
00167
00168 void Geons3D::onSimEventGeons3DPrior(SimEventQueue& q,
00169 rutz::shared_ptr<SimEventGeons3DPrior>& e)
00170 {
00171 itsGeonsState = e->getGeons();
00172 itsGlobalRotation = e->getRotation();
00173 itsGlobalPos = e->getPos();
00174
00175 }
00176
00177
00178 void Geons3D::onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00179 {
00180 if (itsShowDebug.getVal())
00181 {
00182
00183
00184 nub::ref<FrameOstream> ofs =
00185 dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00186 Layout<PixRGB<byte> > disp = getDebugImage(q);
00187 ofs->writeRgbLayout(disp, "Geons3D", FrameInfo("Geons3D", SRC_POS));
00188 }
00189 }
00190
00191
00192 void Geons3D::onSimEventUserInput(SimEventQueue& q, rutz::shared_ptr<SimEventUserInput>& e)
00193 {
00194
00195 LINFO("Got event %s %ix%i key=%i",
00196 e->getWinName(),
00197 e->getMouseClick().i,
00198 e->getMouseClick().j,
00199 e->getKey());
00200
00201 if (strcmp(e->getWinName(), "Geons3D"))
00202 return;
00203
00204 itsLearn = !itsLearn;
00205
00206 if (e->getMouseClick().isValid())
00207 {
00208 }
00209
00210 GeonState& geon = itsProposals[0];
00211 switch(e->getKey())
00212 {
00213 case 104:
00214 geon.pos.x -= 1.0;
00215 break;
00216 case 98:
00217 geon.pos.x += 1.0;
00218 break;
00219 case 100:
00220 geon.pos.y -= 1.0;
00221 break;
00222 case 102:
00223 geon.pos.y += 1.0;
00224 break;
00225 case 21:
00226 geon.pos.z += 1.0;
00227 break;
00228 case 20:
00229 geon.pos.z -= 1.0;
00230 break;
00231 case 38:
00232 geon.rot.x += 5;
00233 break;
00234 case 52:
00235 geon.rot.x -= 5;
00236 break;
00237 case 39:
00238 geon.rot.y += 5;
00239 break;
00240 case 53:
00241 geon.rot.y -= 5;
00242 break;
00243 case 40:
00244 geon.rot.z += 5;
00245 break;
00246 case 54:
00247 geon.rot.z -= 5;
00248 break;
00249
00250 case 10:
00251 geon.superQuadric.its_a1 += 1;
00252 break;
00253 case 24:
00254 geon.superQuadric.its_a1 -= 1;
00255 break;
00256 case 11:
00257 geon.superQuadric.its_a2 += 1;
00258 break;
00259 case 25:
00260 geon.superQuadric.its_a2 -= 1;
00261 break;
00262 case 12:
00263 geon.superQuadric.its_a3 += 1;
00264 break;
00265 case 26:
00266 geon.superQuadric.its_a3 -= 1;
00267 break;
00268 case 13:
00269 geon.superQuadric.its_n += 0.1;
00270 break;
00271 case 27:
00272 geon.superQuadric.its_n -= 0.1;
00273 break;
00274 case 14:
00275 geon.superQuadric.its_e += 0.1;
00276 break;
00277 case 28:
00278 geon.superQuadric.its_e -= 0.1;
00279 break;
00280 case 15:
00281 geon.superQuadric.its_alpha += 0.1;
00282 break;
00283 case 29:
00284 geon.superQuadric.its_alpha -= 0.1;
00285 break;
00286 }
00287
00288 LINFO("Pos(%0.2f,%0.2f,%0.2f), rotation(%0.2f,%0.2f,%0.2f) (%f,%f,%f,%f,%f,%f)",
00289 geon.pos.x, geon.pos.y, geon.pos.z,
00290 geon.rot.x, geon.rot.y, geon.rot.z,
00291 geon.superQuadric.its_a1, geon.superQuadric.its_a2, geon.superQuadric.its_a3,
00292 geon.superQuadric.its_n, geon.superQuadric.its_e,
00293 geon.superQuadric.its_alpha);
00294
00295
00296
00297
00298 }
00299
00300 void Geons3D::calcGeonLikelihood(GeonState& geon)
00301 {
00302 Image<float> edges;
00303 Image<float> surface;
00304 double edgeProb = calcGeonEdgeLikelihood(geon, edges, surface);
00305 double surfaceProb = calcGeonSurfaceLikelihood(geon, edges, surface);
00306
00307 geon.prob = edgeProb * surfaceProb;
00308
00309 }
00310
00311 void Geons3D::drawGeon(const GeonState& geon)
00312 {
00313 }
00314
00315 void Geons3D::renderScene(const GeonState& geon, std::vector<ViewPort3D::Line>& lines, Image<PixRGB<byte> >& frame)
00316 {
00317 itsViewPort->setWireframeMode(true);
00318 itsViewPort->setLightsMode(true);
00319 itsViewPort->setFeedbackMode(true);
00320 itsViewPort->initFrame();
00321
00322 drawGeon(geon);
00323 lines = itsViewPort->getFrameLines();
00324
00325 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00326 drawGeon(geon);
00327
00328 frame = flipVertic(itsViewPort->getFrame());
00329 }
00330
00331 double Geons3D::calcGeonEdgeLikelihood(GeonState& geon, Image<float>& edges, Image<float>& surface)
00332 {
00333
00334 itsViewPort->setWireframeMode(true);
00335 itsViewPort->setLightsMode(true);
00336 itsViewPort->setFeedbackMode(true);
00337 itsViewPort->initFrame();
00338
00339 drawGeon(geon);
00340 std::vector<ViewPort3D::Line> lines = itsViewPort->getFrameLines();
00341
00342 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00343 drawGeon(geon);
00344
00345 Image<PixRGB<byte> > frame = flipVertic(itsViewPort->getFrame());
00346 surface = luminance(frame);
00347
00348
00349 Image<float> edgesMag, edgesOri;
00350 gradientSobel(surface, edgesMag, edgesOri);
00351
00352 Image<float> mag(itsEdgesDT.getDims(),ZEROS);
00353 Image<float> ori(itsEdgesDT.getDims(),ZEROS);
00354
00355 inplaceNormalize(edgesMag, 0.0F, 100.0F);
00356 for(uint i=0; i<lines.size(); i++)
00357 {
00358
00359 double dx = lines[i].p2.i - lines[i].p1.i;
00360 double dy = lines[i].p2.j - lines[i].p1.j;
00361 double ang = atan2(dx,dy) + M_PI/2;
00362
00363 if (ang < 0) ang += M_PI;
00364 if (ang >= M_PI) ang -= M_PI;
00365
00366
00367 Point2D<float> center = lines[i].p1 + Point2D<float>(dx/2,dy/2);
00368 if (edgesMag.coordsOk(Point2D<int>(lines[i].p1)) &&
00369 edgesMag.coordsOk(Point2D<int>(lines[i].p2)) &&
00370 edgesMag.getVal(Point2D<int>(lines[i].p1)) > 10 &&
00371 edgesMag.getVal(Point2D<int>(lines[i].p2)) > 10 &&
00372 edgesMag.getVal(Point2D<int>(center)) > 10)
00373 {
00374 drawLine(mag, Point2D<int>(lines[i].p1), Point2D<int>(lines[i].p2), 1.0F);
00375 drawLine(ori, Point2D<int>(lines[i].p1), Point2D<int>(lines[i].p2), float(ang));
00376 }
00377 }
00378
00379
00380 edges = mag;
00381
00382 return getEdgeProb(itsEdgesDT, ori, mag);
00383
00384 }
00385
00386 double Geons3D::calcGeonSurfaceLikelihood(GeonState& geon, Image<float>& edges, Image<float>& surface)
00387 {
00388
00389 for(uint i=0; i<surface.size(); i++)
00390 if (edges[i] > 0)
00391 surface[i] = 0;
00392
00393 return getSurfaceProb(itsEdgesDT,surface);
00394
00395 }
00396
00397
00398 double Geons3D::getEdgeProb(Image<float>& mag, Image<float>& modelOri, Image<float>& modelMag)
00399 {
00400
00401
00402 double prob = 0;
00403 int pixCount = 0;
00404
00405
00406
00407 int numOfEntries = itsOriEdgesDT.size();
00408 double D = M_PI/numOfEntries;
00409
00410
00411
00412
00413 ImageSet<float> modelOriImg(numOfEntries, modelMag.getDims(), ZEROS);
00414
00415 for(int y=0; y < modelMag.getHeight(); y++)
00416 for(int x=0; x < modelMag.getWidth(); x++)
00417 if (modelMag.getVal(x,y) > 0)
00418 {
00419
00420 float phi = modelOri.getVal(x,y);
00421
00422 int oriIdx = (int)floor(phi/D);
00423
00424 modelOriImg[oriIdx].setVal(x,y, 255.0F);
00425
00426 int oriIdxMin = (oriIdx-1)%numOfEntries;
00427 if (oriIdxMin < 0)
00428 oriIdxMin += numOfEntries;
00429 int oriIdxMax = (oriIdx+1)%numOfEntries;
00430
00431 float v1 = itsOriEdgesDT[oriIdxMin].getVal(x,y);
00432 float v2 = itsOriEdgesDT[oriIdx].getVal(x,y);
00433 float v3 = itsOriEdgesDT[oriIdxMax].getVal(x,y);
00434
00435 prob += std::min(v1, std::min(v2,v3));
00436
00437
00438
00439 pixCount++;
00440 }
00441
00442 return exp(-prob/ double(pixCount*20));
00443 }
00444
00445 double Geons3D::getSurfaceProb(Image<float>& data, Image<float>& model)
00446 {
00447
00448 double prob = 0;
00449 int pixCount = 0;
00450
00451 for(int y=0; y < model.getHeight(); y++)
00452 for(int x=0; x < model.getWidth(); x++)
00453 if (model.getVal(x,y) > 0)
00454 {
00455 prob += (10-data.getVal(x,y));
00456 pixCount++;
00457 }
00458 prob /= (10*pixCount);
00459
00460 return exp(-prob);
00461 }
00462
00463
00464 std::vector<Geons3D::GeonState> Geons3D::proposeGeons(Rectangle& attenLoc)
00465 {
00466
00467 std::vector<Geons3D::GeonState> geons;
00468
00469 return geons;
00470
00471 }
00472
00473 void Geons3D::testLikelihood()
00474 {
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 }
00515
00516
00517 void Geons3D::evolve(SimEventQueue& q)
00518 {
00519
00520
00521
00522
00523
00524
00525
00526
00527 }
00528
00529 Image<PixRGB<byte> > Geons3D::getGeonImage(GeonState& geon)
00530 {
00531
00532 itsViewPort->setWireframeMode(false);
00533 itsViewPort->setLightsMode(true);
00534 itsViewPort->setFeedbackMode(false);
00535
00536 itsViewPort->initFrame();
00537
00538 itsViewPort->setColor(PixRGB<byte>(255,100,100));
00539 glTranslatef(geon.pos.x, geon.pos.y, geon.pos.z);
00540 glRotatef(geon.rot.x, 1,0,0);
00541 glRotatef(geon.rot.y, 0,1,0);
00542 glRotatef(geon.rot.z, 0,0,1);
00543
00544 if (geon.superQuadric.its_alpha >= 0)
00545 geon.superQuadric.solidToroid();
00546 else
00547 geon.superQuadric.solidEllipsoid();
00548
00549 return flipVertic(itsViewPort->getFrame());
00550 }
00551
00552
00553 Layout<PixRGB<byte> > Geons3D::getDebugImage(SimEventQueue& q)
00554 {
00555 Layout<PixRGB<byte> > outDisp;
00556
00557
00558
00559
00560
00561 Image<PixRGB<byte> > inputFrame = itsLGNInput[0];
00562 float nSeg = 20;
00563 const float dTheta = 2*M_PI / (float)nSeg;
00564
00565 for(uint i=0; i<itsSurfaces.size(); i++)
00566 {
00567 const TwoHalfDSketch::SurfaceState& surface = itsSurfaces[i];
00568 float a = surface.a;
00569 float b = surface.b;
00570 float e = surface.e;
00571 float k1 = surface.k1;
00572 float k2 = surface.k2;
00573 float rot = surface.rot;
00574 Point2D<float> p = surface.pos;
00575
00576 for (float theta=surface.start; theta < surface.end; theta += dTheta)
00577 {
00578 Point2D<float> p1 = ellipsoid(a,b, e, theta);
00579 Point2D<float> p2 = ellipsoid(a,b, e, theta + dTheta);
00580
00581 Point2D<float> tmpPos1;
00582 Point2D<float> tmpPos2;
00583
00584
00585 tmpPos1.i = p1.i + p1.j*k1;
00586 tmpPos1.j = p1.i*k2 + p1.j;
00587
00588 tmpPos2.i = p2.i + p2.j*k1;
00589 tmpPos2.j = p2.i*k2 + p2.j;
00590
00591
00592 p1.i = (cos(rot)*tmpPos1.i - sin(rot)*tmpPos1.j) + p.i;
00593 p1.j = (sin(rot)*tmpPos1.i + cos(rot)*tmpPos1.j) + p.j;
00594
00595 p2.i = (cos(rot)*tmpPos2.i - sin(rot)*tmpPos2.j) + p.i;
00596 p2.j = (sin(rot)*tmpPos2.i + cos(rot)*tmpPos2.j) + p.j;
00597
00598 drawLine(inputFrame, (Point2D<int>)p1, (Point2D<int>)p2, PixRGB<byte>(255,0,0));
00599
00600 }
00601 }
00602
00603 Image<PixRGB<byte> > proposalsImg(inputFrame.getDims(), ZEROS);;
00604 for(uint i=0; i<itsProposals.size(); i++)
00605 {
00606 Image<PixRGB<byte> > frame = getGeonImage(itsProposals[i]);
00607 proposalsImg += rescale(frame, inputFrame.getDims());
00608 }
00609
00610 outDisp = hcat(inputFrame, proposalsImg);
00611
00612 return outDisp;
00613
00614 }
00615
00616
00617
00618
00619
00620
00621
00622
00623 #endif
00624