00001
00002 #include "Events/EventRouter.h"
00003 #include "Events/LookoutEvents.h"
00004 #include "Events/TextMsgEvent.h"
00005 #include "Motion/HeadPointerMC.h"
00006 #include "Shared/mathutils.h"
00007 #include "Shared/newmat/newmat.h"
00008
00009 #include "Measures.h"
00010 #include "EllipseData.h"
00011 #include "SphereData.h"
00012 #include "BlobData.h"
00013 #include "PolygonData.h"
00014 #include "ShapeRoot.h"
00015 #include "ShapeLine.h"
00016 #include "ShapeEllipse.h"
00017 #include "ShapeBlob.h"
00018 #include "ShapePolygon.h"
00019 #include "Sketch.h"
00020 #include "visops.h"
00021 #include "VRmixin.h"
00022
00023 #include "MapBuilder.h"
00024 #include "Lookout.h"
00025
00026 namespace DualCoding {
00027
00028 typedef map<ShapeType_t,set<int> > colorMap;
00029
00030 inline float distSq(const NEWMAT::ColumnVector& vec) {
00031 return vec(1)*vec(1) + vec(2)*vec(2) + vec(3)*vec(3);
00032 }
00033
00034 MapBuilder::MapBuilder() :
00035 BehaviorBase("MapBuilder"),
00036 camSkS(VRmixin::getCamSkS()),
00037 camShS(VRmixin::getCamSkS().getDualSpace()),
00038 groundShS(VRmixin::groundShS),
00039 local(maps::local,VRmixin::getLocalSkS()), world(maps::world,VRmixin::getWorldSkS()),
00040 cur(&local), xres(camSkS.getWidth()), yres(camSkS.getHeight()),
00041 ground_plane(4), theAgent(VRmixin::theAgent),
00042 localToWorldMatrix(NEWMAT::IdentityMatrix(4)),
00043 worldToLocalTranslateMatrix(NEWMAT::IdentityMatrix(4)),
00044 worldToLocalRotateMatrix(NEWMAT::IdentityMatrix(4)),
00045 badGazePoints(),
00046 agentAtOrigin(true), requests(), curReq(NULL), idCounter(0), maxDistSq(0),
00047 pointAtID(Lookout::Invalid_LO_ID), scanID(Lookout::Invalid_LO_ID),
00048 nextGazePoint() {}
00049
00050 void MapBuilder::DoStart() {
00051 cout << "MapBuilder::DoStart()\n";
00052 BehaviorBase::DoStart();
00053 erouter->addListener(this,EventBase::textmsgEGID);
00054 }
00055
00056
00057
00058
00059
00060
00061
00062 void MapBuilder::DoStop() {
00063 cout << "MapBuilder::DoStop()\n";
00064 while(!requests.empty()) {
00065 delete requests.front();
00066 requests.pop();
00067 }
00068 curReq = NULL;
00069 camSkS.clear(); camShS.clear();
00070 groundShS.clear();
00071 local.SkS.clear(); local.ShS.clear();
00072 world.SkS.clear(); world.ShS.clear();
00073
00074 badGazePoints.clear();
00075 local.gazePts.clear();
00076 world.gazePts.clear();
00077 setAgent(Point(0,0,0),0);
00078
00079 BehaviorBase::DoStop();
00080 }
00081
00082 unsigned int MapBuilder::executeRequest(const MapBuilderRequest& req) {
00083 switch (req.getRequestType()) {
00084 case MapBuilderRequest::takeSnap:
00085 if (const TakeSnapAtRequest* snapAtReq = dynamic_cast<const TakeSnapAtRequest*>(&req))
00086 requests.push(new TakeSnapAtRequest(*snapAtReq));
00087 else
00088 requests.push(new TakeSnapRequest(*dynamic_cast<const TakeSnapRequest*>(&req)));
00089 break;
00090 case MapBuilderRequest::localMap:
00091 if (const LocalMapTestRequest* testReq = dynamic_cast<const LocalMapTestRequest*>(&req))
00092 requests.push(new LocalMapTestRequest(*testReq));
00093 else
00094 requests.push(new LocalMapRequest(*dynamic_cast<const LocalMapRequest*>(&req)));
00095 break;
00096 case MapBuilderRequest::worldMap:
00097 if (const WorldMapTestRequest* testReq = dynamic_cast<const WorldMapTestRequest*>(&req))
00098 requests.push(new WorldMapTestRequest(*testReq));
00099 else
00100 requests.push(new WorldMapRequest(*dynamic_cast<const WorldMapRequest*>(&req)));
00101 break;
00102 default: return -1U;
00103 };
00104 requests.back()->requestID = idCounter++;
00105
00106
00107 if (requests.size() == 1) {
00108 erouter->addListener(this,EventBase::lookoutEGID);
00109 executeRequest();
00110 }
00111 return requests.back()->requestID;
00112 }
00113
00114 void MapBuilder::executeRequest() {
00115 if ( requests.empty() || curReq != NULL ) return;
00116 curReq = requests.front();
00117 cout << "MapBuilder::executeRequest: execute " << curReq->requestID << endl;
00118 erouter->postEvent(EventBase::mapbuilderEGID, requests.front()->requestID, EventBase::activateETID,0);
00119 if (curReq->groundPlaneAssumption == MapBuilderRequest::onStand)
00120 calculateGroundPlane(MapBuilderRequest::onStand);
00121
00122 if (curReq->getRequestType() == MapBuilderRequest::takeSnap)
00123 if (const TakeSnapAtRequest* snapAtReq = dynamic_cast<const TakeSnapAtRequest*>(curReq))
00124 storeImageAt(snapAtReq->gazePt);
00125 else
00126 storeImage();
00127 else {
00128 const LocalMapRequest& curMapReq = *dynamic_cast<const LocalMapRequest*> (&(*curReq));
00129 maxDistSq = curMapReq.maxDist*curMapReq.maxDist;
00130 cur = (&curMapReq.shs==&local.ShS) ? &local : &world;
00131 if (curMapReq.clearShapes) {
00132 cur->ShS.clear();
00133 cur->SkS.clear();
00134 cur->gazePts.clear();
00135 cur->baseToCamMats.clear();
00136 }
00137 defineGazePts(cur->gazePts, curMapReq.area, curMapReq.doScan);
00138 if ( determineNextGazePoint() )
00139 moveToNextGazePoint();
00140 else
00141 requestComplete();
00142 }
00143 }
00144
00145 void MapBuilder::processEvent(const EventBase &e) {
00146 cout << "MapBuilder::processEvent got " << e.getDescription() << endl;
00147 switch ( e.getGeneratorID() ) {
00148 case EventBase::textmsgEGID: {
00149 const TextMsgEvent &txtev = dynamic_cast<const TextMsgEvent&>(e);
00150 if ( strcmp(txtev.getText().c_str(),"MoveHead") == 0 )
00151 moveToNextGazePoint(true);
00152 break; }
00153 case EventBase::lookoutEGID:
00154
00155 cout << "MapBuilder got event " << e.getName() << " pointAtID=" << pointAtID << endl;
00156 if (e.getSourceID() == pointAtID && e.getTypeID() == EventBase::deactivateETID) {
00157 const Sketch<uchar>& camImg = dynamic_cast<const LookoutSketchEvent*>(&e)->getSketch();
00158 NEW_SKETCH(camFrame, uchar, camImg);
00159 const NEWMAT::Matrix& camToBase = dynamic_cast<const LookoutSketchEvent*>(&e)->toBaseMatrix;
00160 const NEWMAT::Matrix baseToCam = camToBase.i();
00161 processImage(camFrame, camToBase, baseToCam);
00162 if (curReq->getRequestType() == MapBuilderRequest::takeSnap) {
00163 requestComplete();
00164 return;
00165 }
00166 if (cur->space == maps::local)
00167 extendLocal(baseToCam);
00168 else
00169 extendWorld(baseToCam);
00170 }
00171
00172 else if (e.getSourceID() == scanID && e.getTypeID() != EventBase::activateETID) {
00173 const vector<Point>& pts = dynamic_cast<const LookoutScanEvent*>(&e)->getTasks().front()->data;
00174 cur->gazePts.insert(cur->gazePts.end(),pts.begin(), pts.end());
00175 }
00176 else
00177 cout << "MapBuilder::processEvent(): unknown event " << e.getDescription()
00178 << " pointAtID=" << pointAtID << endl;
00179
00180 if ( requestExitTest() || !determineNextGazePoint() )
00181 requestComplete();
00182 else
00183 moveToNextGazePoint();
00184 break;
00185 default:
00186 cout << "Unexpected event " << e.getDescription() << endl;
00187 }
00188 }
00189
00190 void MapBuilder::processImage(const Sketch<uchar>& camFrame,
00191 const NEWMAT::Matrix& camToBase,
00192 const NEWMAT::Matrix& baseToCam) {
00193 if (curReq->groundPlaneAssumption == MapBuilderRequest::onLegs)
00194 calculateGroundPlane(MapBuilderRequest::onLegs);
00195 getCameraShapes(camFrame);
00196 projectToGround(camToBase);
00197 filterGroundShapes(baseToCam);
00198 }
00199
00200 bool MapBuilder::determineNextGazePoint() {
00201 if (&cur->ShS == &world.ShS && !agentAtOrigin) {
00202 cur->ShS.applyTransform(worldToLocalTranslateMatrix);
00203 cur->ShS.applyTransform(worldToLocalRotateMatrix);
00204 bool b = determineNextGazePoint(cur->ShS.allShapes()) || determineNextGazePoint(cur->gazePts);
00205 cur->ShS.applyTransform(localToWorldMatrix);
00206 return b;
00207 }
00208 else
00209 return determineNextGazePoint(cur->ShS.allShapes()) || determineNextGazePoint(cur->gazePts);
00210 }
00211
00212 bool MapBuilder::determineNextGazePoint(const vector<ShapeRoot>& shapes) {
00213 const LocalMapRequest *locReq = dynamic_cast<const LocalMapRequest*>(curReq);
00214 if ( locReq == NULL || ! locReq->pursueShapes )
00215 return false;
00216 HeadPointerMC headpointer_mc;
00217 for (vector<ShapeRoot>::const_iterator it = shapes.begin();
00218 it != shapes.end(); it++) {
00219
00220 if ((*it)->isType(lineDataType) || (*it)->isType(polygonDataType)) {
00221 const Shape<LineData>& ld = ShapeRootTypeConst(*it,LineData);
00222 const Shape<PolygonData>& pd = ShapeRootTypeConst(*it,PolygonData);
00223 bool isLine = (*it)->isType(lineDataType);
00224 EndPoint p[2] = { isLine ? ld->end1Pt(): pd->end1Pt(), isLine ? ld->end2Pt() : pd->end2Pt()};
00225 for (int i = 0; i < 2; i++) {
00226 if (!p[i].isValid() && !isBadGazePoint(p[i])
00227 && badGazePoints.end() == find(badGazePoints.begin(), badGazePoints.end(), (Point) p[i])) {
00228 cout << "take snap at endpoint" << (i+1) << " of shape id "
00229 << (*it)->getId() << " at " << p[i] << endl;
00230 if (!headpointer_mc.lookAtPoint(p[i].coordX(),p[i].coordY(),p[i].coordZ()))
00231 badGazePoints.push_back((Point)p[i]);
00232 nextGazePoint = p[i];
00233 return true;
00234 }
00235 }
00236 }
00237
00238 if ((!(*it)->isType(agentDataType)) &&
00239 (*it)->getConfidence() <= 1 &&
00240 ! isBadGazePoint((*it)->getCentroid()) &&
00241 badGazePoints.end() == find(badGazePoints.begin(), badGazePoints.end(), (*it)->getCentroid())) {
00242 const Point pt = (*it)->getCentroid();
00243 cout << "take snap at shape " << (*it)->getId()
00244 << " (confidence level: " << (*it)->getConfidence() << ")" << endl;
00245 cout << " at " << pt << endl;
00246 if (! headpointer_mc.lookAtPoint(pt.coordX(),pt.coordY(),pt.coordZ()))
00247 badGazePoints.push_back(pt);
00248 nextGazePoint = pt;
00249 return true;
00250 }
00251 cout << "Skipping shape " << (*it)->getId()
00252 << " (confidence level: " << (*it)->getConfidence() << ")" << endl;
00253 }
00254 return false;
00255 }
00256
00257
00258 bool MapBuilder::determineNextGazePoint(vector<Point>& gazePts) {
00259 HeadPointerMC headpointer_mc;
00260 for (vector<Point>::iterator it = gazePts.begin();
00261 it != gazePts.end(); it++) {
00262 cout << "look at pre-defined gazePt: " << *it << endl;
00263 nextGazePoint = *it;
00264 gazePts.erase(it);
00265 return true;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 return false;
00275 }
00276
00277 void MapBuilder::moveToNextGazePoint(const bool manualOverride) {
00278 if ( curReq == NULL ) {
00279 cout << "curReq == NULL in moveToNextGazePoint!" << endl;
00280 return;
00281 }
00282 cout << "curReq == " << (unsigned int)curReq << endl;
00283 const LocalMapRequest* locReq = dynamic_cast<LocalMapRequest*>(curReq);
00284 if ( locReq != NULL && locReq->manualHeadMotion && manualOverride==false ) {
00285 cout << "To proceed to this gaze point: !msg MoveHead" << endl;
00286 return;
00287 }
00288 storeImageAt(nextGazePoint);
00289 }
00290
00291
00292 bool MapBuilder::isBadGazePoint(const Point& Pt) const {
00293 const coordinate_t x = Pt.coordX();
00294 const coordinate_t y = Pt.coordY();
00295 return ( x*x + y*y > maxDistSq ||
00296 x < -30.0);
00297 }
00298
00299 void MapBuilder::storeImageAt(const Point& pt) {
00300 pointAtID = VRmixin::lookout.executeRequest(StoreImageAtRequest(pt));
00301 cout << "MapBuilder sent new storeImageAt request; pointAtID=" << pointAtID << endl;
00302 }
00303
00304 void MapBuilder::storeImage() {
00305 pointAtID = VRmixin::lookout.executeRequest(StoreImageRequest());
00306 cout << "MapBuilder sent new storeImage request; pointAtID=" << pointAtID << endl;
00307 }
00308
00309 void MapBuilder::scan(ScanRequest& req) {
00310 set<int> colors;
00311 for (colorMap::const_iterator it1 = curReq->objectColors.begin();
00312 it1 != curReq->objectColors.end(); it1++)
00313 for (set<int>::const_iterator it2 = it1->second.begin();
00314 it2 != it1->second.end(); it2++)
00315 colors.insert(*it2);
00316 req.addTask(ScanRequest::VisionRegionTask(colors,M_PI/18));
00317 scanID = VRmixin::lookout.executeRequest(req);
00318 }
00319
00320 void MapBuilder::extendLocal(const NEWMAT::Matrix& baseToCam) {
00321 vector<ShapeRoot> all = local.ShS.allShapes();
00322 removeNoise(local.ShS, baseToCam);
00323 matchSrcToDst(groundShS,local.ShS,curReq->objectColors[polygonDataType]);
00324 removeGazePts(local.gazePts, baseToCam);
00325 local.baseToCamMats.push_back(baseToCam);
00326 }
00327
00328 void MapBuilder::extendWorld(const NEWMAT::Matrix& baseToCam) {
00329 if (!agentAtOrigin) {
00330 world.ShS.applyTransform(worldToLocalTranslateMatrix);
00331 world.ShS.applyTransform(worldToLocalRotateMatrix);
00332 }
00333 removeNoise(world.ShS, baseToCam);
00334 matchSrcToDst(groundShS,world.ShS,curReq->objectColors[polygonDataType]);
00335 if (!agentAtOrigin)
00336 world.ShS.applyTransform(localToWorldMatrix);
00337 removeGazePts(world.gazePts,baseToCam);
00338 world.baseToCamMats.push_back(baseToCam);
00339 }
00340
00341 bool MapBuilder::requestExitTest() {
00342 if (const LocalMapTestRequest* localTestReq = dynamic_cast<const LocalMapTestRequest*>(curReq))
00343 return ((*localTestReq->exitTest)());
00344 else if (const WorldMapTestRequest* worldTestReq = dynamic_cast<const WorldMapTestRequest*>(curReq))
00345 return ((*worldTestReq->exitTest)());
00346 else
00347 return false;
00348 }
00349
00350 void MapBuilder::requestComplete() {
00351 const unsigned int reqID = curReq->requestID;
00352 cout << "MapBuilderRequest " << reqID << " complete\n";
00353 delete curReq;
00354 curReq = NULL;
00355 requests.pop();
00356 if ( requests.empty() )
00357 erouter->removeListener(this,EventBase::lookoutEGID);
00358 erouter->postEvent(EventBase::mapbuilderEGID, reqID, EventBase::statusETID,0);
00359 executeRequest();
00360 }
00361
00362 void MapBuilder::setAgent(const Point &location, const AngTwoPi heading) {
00363 theAgent->setCentroidPt(location);
00364 theAgent->setOrientation(heading);
00365 const coordinate_t dx = location.coordX();
00366 const coordinate_t dy = location.coordY();
00367 const coordinate_t dz = location.coordZ();
00368 float localToWorld[] = {cos(heading), -sin(heading), 0, dx,
00369 sin(heading),cos(heading), 0, dy,
00370 0, 0, 1, dz,
00371 0 ,0, 0, 1};
00372 float worldToLocalTrans[] = {1, 0, 0, -dx,
00373 0, 1, 0, -dy,
00374 0, 0, 1, -dz,
00375 0 ,0, 0, 1};
00376 float worldToLocalRotate[] = {cos(heading), sin(heading), 0, 0,
00377 -sin(heading),cos(heading), 0, 0,
00378 0, 0, 1, 0,
00379 0 ,0, 0, 1};
00380 localToWorldMatrix << localToWorld;
00381 worldToLocalTranslateMatrix << worldToLocalTrans;
00382 worldToLocalRotateMatrix << worldToLocalRotate;
00383 agentAtOrigin = (heading == 0 || heading == 2*M_PI) && dx == 0 && dy == 0;
00384 }
00385
00386 void MapBuilder::moveAgent(coordinate_t const local_dx, coordinate_t const local_dy, AngTwoPi dtheta) {
00387 AngTwoPi const heading = theAgent->getOrientation();
00388 float const c = cos(heading);
00389 float const s = sin(heading);
00390 float const dx = local_dx*c + local_dy*-s;
00391 float const dy = local_dx*s + local_dy*c;
00392 setAgent(Point(dx+theAgent->getCentroid().coordX(),
00393 dy+theAgent->getCentroid().coordY(),
00394 theAgent->getCentroid().coordZ()),
00395 dtheta+heading);
00396 }
00397
00398 void MapBuilder::importLocalToWorld() {
00399 if (!agentAtOrigin) {
00400 world.ShS.applyTransform(worldToLocalTranslateMatrix);
00401 world.ShS.applyTransform(worldToLocalRotateMatrix);
00402 }
00403 matchSrcToDst(local.ShS, world.ShS);
00404 if (!agentAtOrigin)
00405 world.ShS.applyTransform(localToWorldMatrix);
00406 }
00407
00408
00409 void MapBuilder::importWorldToLocal(const ShapeRoot &worldShape) {
00410 ShapeRoot localShape(local.ShS.importShape(worldShape));
00411 localShape->applyTransform(worldToLocalTranslateMatrix);
00412 localShape->applyTransform(worldToLocalRotateMatrix);
00413 }
00414
00415 bool MapBuilder::isPointVisible(const Point &pt, const NEWMAT::Matrix& baseToCam, float maxDistanceSq) {
00416 NEWMAT::ColumnVector camCoords = baseToCam*pt.coords;
00417 if (camCoords(3) <=0 || distSq(camCoords) >= maxDistanceSq) return false;
00418 float normX,normY;
00419 config->vision.computePixel(camCoords(1),camCoords(2),camCoords(3),normX,normY);
00420 return (fabs(normX) < 0.9 && fabs(normY) < 0.9);
00421 }
00422
00423 bool MapBuilder::isLineVisible(const LineData& ln, const NEWMAT::Matrix& baseToCam) {
00424 float normX1,normX2,normY1,normY2;
00425 NEWMAT::ColumnVector camCoords(4);
00426 camCoords = baseToCam*ln.end1Pt().coords;
00427 config->vision.computePixel(camCoords(1),camCoords(2),camCoords(3),normX1,normY1);
00428 camCoords = baseToCam*ln.end2Pt().coords;
00429 config->vision.computePixel(camCoords(1),camCoords(2),camCoords(3),normX2,normY2);
00430 const bool end1Pt_visible = fabs(normX1) < 0.9 && fabs(normY1) < 0.9;
00431 const bool end2Pt_visible = fabs(normX2) < 0.9 && fabs(normY2) < 0.9;
00432 if (end1Pt_visible && end2Pt_visible)
00433 return true;
00434 LineData lnCam(VRmixin::groundShS, Point(normX1,normY1), Point(normX2,normY2));
00435
00436 LineData camBounds[] = {LineData(VRmixin::groundShS, Point(0.9,0.9),Point(0.9,-0.9)),
00437 LineData(VRmixin::groundShS, Point(0.9,-0.9),Point(-0.9,-0.9)),
00438 LineData(VRmixin::groundShS, Point(-0.9,-0.9),Point(-0.9,0.9)),
00439 LineData(VRmixin::groundShS, Point(-0.9,0.9),Point(0.9,0.9))};
00440 unsigned int ptCount = 0;
00441 Point p[2];
00442
00443 if (end1Pt_visible) p[ptCount++].setCoords(normX1,normY1,0);
00444 else if (end2Pt_visible) p[ptCount++].setCoords(normX2,normY2,0);
00445 for (int i = 0; i < 4; i++)
00446 if (camBounds[i].intersectsLine(lnCam)) {
00447 p[ptCount++].setCoords(lnCam.intersectionWithLine(camBounds[i]));
00448
00449 if (ptCount > 1)
00450 return p[0].distanceFrom(p[1]) > 0.1;
00451 }
00452 return false;
00453 }
00454
00455 bool MapBuilder::isShapeVisible(const ShapeRoot &ground_shape, const NEWMAT::Matrix& baseToCam,
00456 float maxDistanceSq) {
00457 if (ground_shape->isType(lineDataType))
00458 return isLineVisible(ShapeRootTypeConst(ground_shape,LineData).getData(), baseToCam);
00459 else if (ground_shape->isType(polygonDataType)) {
00460 const Shape<PolygonData>& polygon = ShapeRootTypeConst(ground_shape,PolygonData);
00461 for (vector<LineData>::const_iterator edge_it = polygon->getEdges().begin();
00462 edge_it != polygon->getEdges().end(); edge_it++)
00463 if (isLineVisible(*edge_it,baseToCam))
00464 return true;
00465 return false;
00466 }
00467 else
00468 return isPointVisible(ground_shape->getCentroid(), baseToCam, maxDistanceSq);
00469 }
00470
00471
00472
00473
00474
00475 void MapBuilder::filterGroundShapes(const NEWMAT::Matrix& baseToCam) {
00476
00477 vector<ShapeRoot> ground_shapes = groundShS.allShapes();
00478
00479 for (vector<ShapeRoot>::iterator ground_it = ground_shapes.begin();
00480 ground_it != ground_shapes.end(); ground_it++ ) {
00481 const coordinate_t cenX = (*ground_it)->getCentroid().coordX();
00482 const coordinate_t cenY = (*ground_it)->getCentroid().coordY();
00483 if (cenX*cenX + cenY*cenY > maxDistSq) {
00484 cout << "ground shape " << (*ground_it)->getId() << "(lastMatch "
00485 << (*ground_it)->getLastMatchId() << ") too far, delete\n";
00486 ground_it->deleteShape();
00487 }
00488 NEWMAT::ColumnVector coords = Kinematics::pack(cenX,cenY,(*ground_it)->getCentroid().coordZ());
00489 coords = baseToCam*coords;
00490 if (coords(3) < 0) {
00491 cout << "Projection failed for ground shape " << (*ground_it)->getId()
00492 << "(lastMatch " << (*ground_it)->getLastMatchId() << "), delete\n";
00493 ground_it->deleteShape();
00494 }
00495
00496 else if ((*ground_it)->isType(lineDataType)) {
00497 const Shape<LineData>& line = ShapeRootTypeConst(*ground_it,LineData);
00498 const coordinate_t e1x = line->end1Pt().coordX();
00499 const coordinate_t e1y = line->end1Pt().coordY();
00500 const coordinate_t e2x = line->end2Pt().coordX();
00501 const coordinate_t e2y = line->end2Pt().coordY();
00502 if (e1x*e1x + e1y*e1y > maxDistSq && e2x*e2x + e2y*e2y > maxDistSq)
00503 ground_it->deleteShape();
00504 else if (e1x*e1x + e1y*e1y > maxDistSq || e2x*e2x + e2y*e2y > maxDistSq) {
00505
00506
00507 vector<float> line_abc = line->lineEquation_abc();
00508 Point pt;
00509 const EndPoint* far_ept = (e1x*e1x + e1y*e1y > maxDistSq) ? &line->end1Pt() : &line->end2Pt();
00510 if (line_abc[1] == 0.0) {
00511 const coordinate_t y_abs = sqrt(maxDistSq - line_abc[2]*line_abc[2]);
00512 if (fabs(far_ept->coordY()-y_abs) < fabs(far_ept->coordY()+y_abs))
00513 pt.setCoords(e1x, y_abs, far_ept->coordZ());
00514 else
00515 pt.setCoords(e1x, -y_abs, far_ept->coordZ());
00516 }
00517 else {
00518 const float a = - line_abc[0]/line_abc[1];
00519 const float b = line_abc[2]/line_abc[1];
00520 const coordinate_t x1 = (sqrt((a*a+1.0)*maxDistSq-b*b)-a*b)/(a*a+1.0);
00521 const coordinate_t x2 = (-sqrt((a*a+1.0)*maxDistSq-b*b)-a*b)/(a*a+1.0);
00522 if (fabs(far_ept->coordX()-x1) < fabs(far_ept->coordX()-x2))
00523 pt.setCoords(x1, a*x1+b, far_ept->coordZ());
00524 else
00525 pt.setCoords(x2, a*x2+b, far_ept->coordZ());
00526 }
00527 EndPoint temp_endPt(pt);
00528 temp_endPt.setValid(false);
00529
00530
00531 if (e1x*e1x + e1y*e1y > maxDistSq)
00532 line->setEndPts(temp_endPt, line->end2Pt());
00533 else
00534 line->setEndPts(line->end1Pt(), temp_endPt);
00535 badGazePoints.push_back(pt);
00536 }
00537 }
00538 }
00539 }
00540
00541 void MapBuilder::calculateGroundPlane(const MapBuilderRequest::GroundPlaneAssumption_t& gpa) {
00542 switch(gpa) {
00543 case MapBuilderRequest::onLegs:
00544 ground_plane << kine->calculateGroundPlane();
00545 cout << "Neck pan = " << state->outputs[HeadOffset+PanOffset] << endl;
00546 cout << "Calculated ground plane: " << NEWMAT::printmat(ground_plane) << endl;
00547 break;
00548 case MapBuilderRequest::onStand:
00549 #ifdef TGT_ERS210
00550 ground_plane << 0 << 0 << (float)(-1/200.0) << 1;
00551 #else
00552 ground_plane << 0 << 0 << (float)(-1/170.0) << 1;
00553 #endif
00554
00555 break;
00556 };
00557 }
00558
00559 void MapBuilder::projectToGround(const NEWMAT::Matrix& camToBase) {
00560 VRmixin::projectToGround(camToBase, ground_plane);
00561 }
00562
00563
00564 void MapBuilder::matchSrcToDst(ShapeSpace &srcShS, ShapeSpace &dstShS,
00565 set<int> polCols, bool mergeSrc, bool mergeDst) {
00566 vector<ShapeRoot> src_shapes = srcShS.allShapes();
00567 vector<ShapeRoot> dst_shapes = dstShS.allShapes();
00568 vector<LineData> polygon_edges;
00569
00570
00571 for (vector<ShapeRoot>::iterator src_it = src_shapes.begin();
00572 src_it != src_shapes.end(); src_it++ ) {
00573 if (!(*src_it)->isAdmissible()) {
00574 cout << "shape " << (*src_it)->getId() << "(lastMatch "
00575 << (*src_it)->getLastMatchId() << ") is not admissible:" << endl;
00576 (*src_it)->printParams();
00577 src_shapes.erase(src_it--);
00578 }
00579 else if ((*src_it)->isType(polygonDataType)) {
00580 const vector<LineData>& lines = ShapeRootTypeConst(*src_it, PolygonData)->getEdges();
00581 polygon_edges.insert(polygon_edges.end(), lines.begin(), lines.end());
00582 src_shapes.erase(src_it--);
00583 }
00584 else if ((*src_it)->isType(lineDataType)) {
00585 const int colorIndex = ProjectInterface::getColorIndex((*src_it)->getColor());
00586 if ( polCols.end() != find(polCols.begin(), polCols.end(), colorIndex)) {
00587 polygon_edges.push_back(ShapeRootTypeConst(*src_it, LineData).getData());
00588 src_shapes.erase(src_it--);
00589 }
00590 }
00591 }
00592
00593
00594 if (mergeSrc)
00595 for ( vector<ShapeRoot>::iterator it = src_shapes.begin();
00596 it != src_shapes.end(); it++ )
00597 for ( vector<ShapeRoot>::iterator it2 = it+1;
00598 it2 != src_shapes.end(); it2++)
00599 if ((*it2)->isMatchFor(*it) && (*it)->updateParams(*it2)) {
00600 cout << "merging shape " << (*it)->getId() << " and shape " << (*it2)->getId() << endl;
00601 src_shapes.erase(it2--);
00602 }
00603
00604 vector<Shape<PolygonData> > existingPolygons;
00605
00606 for (vector<ShapeRoot>::iterator dst_it = dst_shapes.begin();
00607 dst_it != dst_shapes.end(); dst_it++ )
00608 if ((*dst_it)->isType(polygonDataType))
00609 existingPolygons.push_back(ShapeRootType(*dst_it,PolygonData));
00610 else {
00611 for (vector<ShapeRoot>::iterator src_it = src_shapes.begin();
00612 src_it != src_shapes.end(); src_it++)
00613 if ((*dst_it)->isMatchFor(*src_it) && (*dst_it)->updateParams((*src_it))) {
00614 (*dst_it)->increaseConfidence(*src_it);
00615
00616
00617 src_shapes.erase(src_it--);
00618 }
00619 }
00620
00621
00622 vector<ShapeRoot> deletedPolygons;
00623
00624 vector<ShapeRoot> newPolygons = PolygonData::formPolygons(polygon_edges,existingPolygons,deletedPolygons);
00625
00626 for (vector<ShapeRoot>::iterator delete_it = deletedPolygons.begin();
00627 delete_it != deletedPolygons.end(); delete_it++)
00628 delete_it->deleteShape();
00629 dstShS.importShapes(newPolygons);
00630 dstShS.importShapes(src_shapes);
00631 cout << "Imported " << (src_shapes.size()+newPolygons.size()) << " new shape(s) from "
00632 << srcShS.name << "ShS to " << dstShS.name << "ShS\n";
00633
00634
00635 if (mergeDst) {
00636 dst_shapes = dstShS.allShapes();
00637 for ( vector<ShapeRoot>::iterator it = dst_shapes.begin();
00638 it < dst_shapes.end(); it++ )
00639 for ( vector<ShapeRoot>::iterator it2 = it+1;
00640 it2 < dst_shapes.end(); it2++)
00641 if ((*it2)->isMatchFor(*it) && (*it)->updateParams(*it2,true)) {
00642
00643
00644
00645
00646 it2->deleteShape();
00647 dst_shapes.erase(it2--);
00648 }
00649 }
00650 }
00651
00652
00653
00654 void MapBuilder::removeNoise(ShapeSpace& ShS, const NEWMAT::Matrix& baseToCam) {
00655
00656 vector<ShapeRoot> shapes = ShS.allShapes();
00657 for (vector<ShapeRoot>::iterator it = shapes.begin();
00658 it != shapes.end(); it++ ) {
00659
00660
00661 if (curReq->objectColors[(*it)->getType()].find(ProjectInterface::getColorIndex((*it)->getColor())) ==
00662 curReq->objectColors[(*it)->getType()].end())
00663 continue;
00664 if ((*it)->isType(polygonDataType)) {
00665 Shape<PolygonData>& polygon = ShapeRootType(*it,PolygonData);
00666 vector<LineData>& edges = polygon->getEdgesRW();
00667 unsigned int edge_index = 0;
00668 for (vector<LineData>::iterator edge_it = edges.begin();
00669 edge_it != edges.end(); edge_it++, edge_index++) {
00670 if (isLineVisible(*edge_it, baseToCam)) {
00671 cout << "edge " << edge_index << " of polygon " << (*it)->getId() << "(confidence: "
00672 << edge_it->getConfidence() << ") should be visible in this frame" << endl;
00673 edge_it->decreaseConfidence();
00674 }
00675 }
00676 vector<ShapeRoot> brokenPolygons = polygon->updateState();
00677 ShS.importShapes(brokenPolygons);
00678 if (!polygon->isAdmissible()) {
00679 cout << "delete polygon " << (*it)->getId() << " from map" << endl;
00680 it->deleteShape();
00681 }
00682 }
00683 else if ((!(*it)->isType(agentDataType)) && isShapeVisible(*it, baseToCam, maxDistSq)){
00684 (*it)->decreaseConfidence();
00685 cout << "shape " << (*it)->getId() << "(confidence: " << (*it)->getConfidence()
00686 << ") should be visible in this frame" << endl;
00687 if ((*it)->getConfidence() < 0 ) {
00688 cout << "confidence < 0, shape " << (*it)->getId() << " deleted from map" << endl;
00689
00690 }
00691 }
00692 }
00693 }
00694
00695
00696
00697 void MapBuilder::defineGazePts(vector<Point> &gazePts, const ShapeRoot& area, bool doScan) {
00698 cout << "MapBuilder::defineGazePts\n";
00699 static const float meshSize=50;
00700 switch (area->getType()) {
00701 case lineDataType: {
00702 const Shape<LineData>& line = ShapeRootTypeConst(area,LineData);
00703 if (doScan) {
00704 ScanAlongLineRequest req(line->end1Pt(),line->end2Pt());
00705 scan(req);
00706 }
00707 else {
00708 int numIntervals = (int) (line->getLength()/meshSize);
00709 const EndPoint& ep1 = line->end1Pt();
00710 const EndPoint& ep2 = line->end2Pt();
00711 gazePts.push_back(ep1);
00712 for (int i = 1; i < numIntervals; i++)
00713 gazePts.push_back((ep1*i + ep2*(numIntervals-i))/numIntervals);
00714 gazePts.push_back(ep2);
00715 }
00716 }
00717 break;
00718 case blobDataType: {
00719 const Shape<BlobData>& blob = ShapeRootTypeConst(area,BlobData);
00720 if (doScan) {
00721 ScanAreaRequest req(blob->topLeft.coordY(),blob->bottomRight.coordY(),
00722 blob->topLeft.coordX(),blob->bottomRight.coordX());
00723 scan(req);
00724 }
00725 else {
00726 vector<Point> corners;
00727 corners.push_back(blob->topLeft);
00728 corners.push_back(blob->topRight);
00729 corners.push_back(blob->bottomRight);
00730 corners.push_back(blob->bottomLeft);
00731 defineGazePts(gazePts, corners, meshSize);
00732 }
00733 }
00734 break;
00735 case pointDataType:
00736 gazePts.push_back(area->getCentroid());
00737 break;
00738 case polygonDataType: {
00739 const Shape<PolygonData> &poly = ShapeRootTypeConst(area,PolygonData);
00740 const vector<Point> &verts = poly->getVertices();
00741 gazePts.insert(gazePts.end(),verts.begin(),verts.end());
00742 }
00743 break;
00744 default:
00745 cerr << "ERRORR MapBuilder::defineGazePts: Only types of area supported are Blob, Line, Point, and Polygon\n";
00746 requestComplete();
00747 break;
00748 };
00749 }
00750
00751 void MapBuilder::defineGazePts(vector<Point>& gazePts, const vector<Point>& corners, float meshSize) {
00752 if (corners.size() != 4) {
00753 cout << "Region of interest has to have four corners" << endl;
00754 return;
00755 }
00756 for (vector<Point>::const_iterator it = corners.begin();
00757 it != corners.end()-1; it++) {
00758 if (find(it+1, corners.end(), *it) != corners.end()) {
00759 cout << "At least two corners are identical" << endl;
00760 return;
00761 }
00762 }
00763 LineData ln1(groundShS, corners.at(0),corners.at(1));
00764 LineData ln2(groundShS, corners.at(0),corners.at(2));
00765 const bool edge0_next_to_edge1 = !ln1.intersectsLine(LineData(groundShS, corners.at(2),corners.at(3)));
00766 const bool edge0_next_to_edge2 = !ln2.intersectsLine(LineData(groundShS, corners.at(1),corners.at(3)));
00767 vector<LineData> horizontal, vertical;
00768
00769
00770 const Point p0(corners.at(0));
00771 const Point p1(edge0_next_to_edge1 ? corners.at(1) : corners.at(3));
00772 const Point p2(edge0_next_to_edge1 ? (edge0_next_to_edge2 ? corners.at(3) : corners.at(2)) : corners.at(1));
00773 const Point p3(edge0_next_to_edge2 ? corners.at(2) : corners.at(3));
00774
00775
00776 Point p1_minus_p0 = p1-p0;
00777 Point p2_minus_p3 = p2-p3;
00778 const int num_steps_x =
00779 (int) (sqrt(max(p1_minus_p0.coordX()*p1_minus_p0.coordX() + p1_minus_p0.coordY()*p1_minus_p0.coordY(),
00780 p2_minus_p3.coordX()*p2_minus_p3.coordX() + p2_minus_p3.coordY()*p2_minus_p3.coordY()))
00781 / meshSize) + 1;
00782 p1_minus_p0 /= (float) num_steps_x;
00783 p2_minus_p3 /= (float) num_steps_x;
00784
00785 for (int i = 0; i <= num_steps_x; i++)
00786 horizontal.push_back(LineData(groundShS, p0+p1_minus_p0*i, p3+p2_minus_p3*i));
00787
00788
00789 Point p3_minus_p0 = p3-p0;
00790 Point p2_minus_p1 = p2-p1;
00791 const int num_steps_y =
00792 (int) (sqrt(max(p3_minus_p0.coordX()*p3_minus_p0.coordX() + p3_minus_p0.coordY()*p3_minus_p0.coordY(),
00793 p2_minus_p1.coordX()*p2_minus_p1.coordX() + p2_minus_p1.coordY()*p2_minus_p1.coordY()))
00794 / meshSize) + 1;
00795 p3_minus_p0 /= (float) num_steps_y;
00796 p2_minus_p1 /= (float) num_steps_y;
00797
00798 for (int i = 0; i <= num_steps_y; i++)
00799 vertical.push_back(LineData(groundShS, p0+p3_minus_p0*i, p1+p2_minus_p1*i));
00800
00801
00802
00803 for (vector<LineData>::const_iterator H_it = horizontal.begin();
00804 H_it != horizontal.end(); H_it++)
00805 for (vector<LineData>::const_iterator V_it = vertical.begin();
00806 V_it != vertical.end(); V_it++)
00807 gazePts.push_back(H_it->intersectionWithLine(*V_it));
00808 }
00809
00810 void MapBuilder::removeGazePts(vector<Point> &gazePts, const NEWMAT::Matrix& baseToCam) {
00811 if ( ! dynamic_cast<const LocalMapRequest*>(curReq)->removePts )
00812 return;
00813 int num_points_seen = 0;
00814 for ( vector<Point>::iterator it = gazePts.begin();
00815 it != gazePts.end(); it++ ) {
00816 if (isPointVisible(*it, baseToCam, maxDistSq)) {
00817 num_points_seen++;
00818 gazePts.erase(it--);
00819 }
00820 }
00821
00822
00823 }
00824
00825
00826
00827
00828
00829 void MapBuilder::printShS(ShapeSpace &ShS) const {
00830 cout << "MapBuilder::printShS()" << endl;
00831 unsigned int line_count = 0;
00832 vector<ShapeRoot> shapes = ShS.allShapes();
00833 for (vector<ShapeRoot>::const_iterator it = shapes.begin();
00834 it != shapes.end(); it++) {
00835 if ((*it)->isType(lineDataType)) {
00836 const Shape<LineData>& ld = ShapeRootTypeConst(*it,LineData);
00837 cout << (*it)->getId() << " " << lineDataType << " "
00838 << ProjectInterface::getColorIndex((*it)->getColor())
00839 << " " << ld->end1Pt().coordX() << " " << ld->end1Pt().coordY()
00840 << " " << ++line_count << " " << ld->getLength() << " " << ld->end1Pt().isValid() << endl;
00841 cout << (*it)->getId() << " " << lineDataType << " "
00842 << ProjectInterface::getColorIndex((*it)->getColor())
00843 << " " << ld->end2Pt().coordX() << " " << ld->end2Pt().coordY()
00844 << " " << line_count << " " << ld->getLength() << " " << ld->end2Pt().isValid() << endl;
00845 }
00846 else {
00847 cout << (*it)->getId() << " " << (*it)->getType() << " "
00848 << ProjectInterface::getColorIndex((*it)->getColor())
00849 << " " << (*it)->getCentroid().coordX() << " " << (*it)->getCentroid().coordY() << endl;
00850 }
00851 }
00852 }
00853
00854
00855
00856
00857
00858 void MapBuilder::getCameraShapes(const Sketch<uchar>& camFrame) {
00859 camShS.clear();
00860 getCamLines(camFrame, curReq->objectColors[lineDataType], curReq->occluderColors[lineDataType]);
00861 getCamEllipses(camFrame, curReq->objectColors[ellipseDataType], curReq->occluderColors[ellipseDataType]);
00862 getCamPolygons(camFrame, curReq->objectColors[polygonDataType], curReq->occluderColors[polygonDataType]);
00863 getCamSpheres(camFrame, curReq->objectColors[sphereDataType], curReq->occluderColors[sphereDataType]);
00864 getCamWalls(camFrame, curReq->floorColor);
00865 BlobData::extractBlobs(camFrame, curReq->objectColors[blobDataType]);
00866 }
00867
00868 vector<Shape<LineData> > MapBuilder::getCamLines(const Sketch<uchar> &camFrame, const set<int>& objectColors,
00869 const set<int>& occluderColors) const {
00870 vector<Shape<LineData> > lines;
00871 if (objectColors.empty() )
00872 return lines;
00873 cout << "*** Find the lines ***" << endl;
00874 NEW_SKETCH_N(occluders,bool,visops::zeros(camFrame));
00875 for ( set<int>::const_iterator it = occluderColors.begin();
00876 it != occluderColors.end(); it++ )
00877 occluders |= visops::minArea(visops::colormask(camFrame,*it));
00878
00879 for (set<int>::const_iterator it = objectColors.begin();
00880 it != objectColors.end(); it++) {
00881 NEW_SKETCH_N(colormask,bool,visops::colormask(camFrame,*it));
00882 NEW_SKETCH_N(cleancolor,bool,visops::minArea(colormask));
00883 NEW_SKETCH_N(fatmask,bool,visops::fillin(cleancolor,1,2,8));
00884 NEW_SKETCH_N(skel,bool,visops::skel(fatmask));
00885 vector<Shape<LineData> > line_shapes = LineData::extractLines(skel,cleancolor|occluders);
00886 lines.insert(lines.end(), line_shapes.begin(), line_shapes.end());
00887 cout << "Found " << line_shapes.size() << " lines." << endl;
00888 }
00889 return lines;
00890 }
00891
00892 vector<Shape<EllipseData> >
00893 MapBuilder::getCamEllipses(const Sketch<uchar> &camFrame,
00894 const set<int>& objectColors, const set<int>& ) const {
00895 vector<Shape<EllipseData> > ellipses;
00896 if (objectColors.empty())
00897 return ellipses;
00898 cout << "*** Find the ellipses ***" << endl;
00899 for (set<int>::const_iterator it = objectColors.begin();
00900 it !=objectColors.end(); it++) {
00901 NEW_SKETCH_N(colormask,bool,visops::colormask(camFrame,*it));
00902 vector<Shape<EllipseData> > ellipse_shapes = EllipseData::extractEllipses(colormask);
00903 ellipses.insert(ellipses.end(), ellipse_shapes.begin(),ellipse_shapes.begin());
00904 cout << "Found " << ellipse_shapes.size() << " ellipses." << endl;
00905 }
00906 return ellipses;
00907 }
00908
00909 vector<Shape<PolygonData> >
00910 MapBuilder::getCamPolygons(const Sketch<uchar> &camFrame,
00911 const set<int>& objectColors, const set<int>& occluderColors) const {
00912 vector<Shape<PolygonData> > polygons;
00913 if ( objectColors.empty() )
00914 return polygons;
00915 cout << "*** Find the polygons ***" << endl;
00916 NEW_SKETCH_N(occluders,bool,visops::zeros(camFrame));
00917 for ( set<int>::const_iterator it = occluderColors.begin();
00918 it !=occluderColors.end(); it++ )
00919 occluders |= visops::colormask(camFrame,*it);
00920
00921 for (set<int>::const_iterator it = objectColors.begin();
00922 it !=objectColors.end(); it++) {
00923 NEW_SKETCH_N(colormask,bool,visops::colormask(camFrame,*it));
00924 NEW_SKETCH_N(fatmask,bool,visops::fillin(colormask,1,2,8));
00925 NEW_SKETCH_N(skel,bool,visops::skel(fatmask));
00926 NEW_SKETCH_N(fatskel,bool,visops::fillin(skel,1,2,8));
00927
00928 vector<Shape<LineData> > polygon_lines = PolygonData::extractPolygonEdges(fatskel,fatmask|occluders);
00929 polygons.insert(polygons.end(), polygon_lines.begin(), polygon_lines.end());
00930 cout << "Found " << polygon_lines.size() << " lines." << endl;
00931 }
00932 return polygons;
00933 }
00934
00935 vector<Shape<SphereData> >
00936 MapBuilder::getCamSpheres(const Sketch<uchar> &camFrame,
00937 const set<int>& objectColors, const set<int>& ) const {
00938 vector<Shape<SphereData> > spheres;
00939 if ( objectColors.empty() )
00940 return spheres;
00941 cout << "*** Find the spheres ***" << endl;
00942 for (set<int>::const_iterator it = objectColors.begin();
00943 it !=objectColors.end(); it++) {
00944 NEW_SKETCH_N(colormask,bool,visops::colormask(camFrame,*it));
00945 vector<ShapeRoot> sphere_shapes = SphereData::extractSpheres(colormask);
00946 spheres.insert(spheres.end(), spheres.begin(), spheres.end());
00947 cout << "Found " << sphere_shapes.size() << " spheres." << endl;
00948 }
00949 return spheres;
00950 }
00951
00952 vector<Shape<LineData> >
00953 MapBuilder::getCamWalls(const Sketch<uchar> &camFrame, unsigned int floorColor) const {
00954 if (floorColor == 0)
00955 return vector<Shape<LineData> >();
00956 cout << "*** Find the walls ***" << endl;
00957 const int camFrame_offset = 8;
00958
00959 NEW_SKETCH_N(colormask,bool,visops::colormask(camFrame,floorColor));
00960 NEW_SKETCH_N(fillinmask ,bool,visops::fillin(colormask, 1, 6, 8));
00961 NEW_SKETCH_N(fillinmask2 ,bool,visops::fillin(fillinmask, 2, 3, 8));
00962 NEW_SKETCH_N(edgemask ,bool,visops::fillin(fillinmask2, 1, 5, 7));
00963 NEW_SKETCH_N(edgemask2 ,bool,visops::non_bounds(edgemask, camFrame_offset));
00964
00965 NEW_SKETCH_N(occluders_floor, bool, camFrame != uchar(0) & camFrame != uchar(floorColor));
00966 NEW_SKETCH_N(occ_mask ,bool,visops::fillin(occluders_floor, 1, 8, 8));
00967 usint const clear_dist = 15;
00968 Sketch<bool> not_too_close = (visops::edist(occ_mask) >= clear_dist);
00969 edgemask2 &= not_too_close;
00970
00971 NEW_SKETCH_N(fatmask ,bool,visops::fillin(edgemask2,2,2,8));
00972 NEW_SKETCH_N(skel,bool,visops::skel(fatmask));
00973 NEW_SKETCH_N(fatskel,bool,visops::fillin(skel,1,2,8));
00974
00975 vector<Shape<LineData> > wall_bounds = PolygonData::extractPolygonEdges(fatskel,fatmask|occluders_floor);
00976
00977
00978
00979 for (vector<Shape<LineData> >::iterator it = wall_bounds.begin();
00980 it != wall_bounds.end(); it++) {
00981 if (((*it)->end1Pt().coordX() < camFrame_offset*2.0 || (*it)->end1Pt().coordX() > xres - camFrame_offset*2.0
00982 || (*it)->end1Pt().coordY() < camFrame_offset*2.0 || (*it)->end1Pt().coordY() > yres - camFrame_offset*2.0)
00983 && (*it)->end1Pt().isValid())
00984 (*it)->end1Pt().setValid(false);
00985 if (((*it)->end2Pt().coordX() < camFrame_offset*2.0 || (*it)->end2Pt().coordX() > xres - camFrame_offset*2.0
00986 || (*it)->end2Pt().coordY() < camFrame_offset*2.0 || (*it)->end2Pt().coordY() > yres - camFrame_offset*2.0)
00987 && (*it)->end2Pt().isValid())
00988 (*it)->end2Pt().setValid(false);
00989 }
00990
00991 cout << "Found " << wall_bounds.size() << " wall boundary lines" << endl;
00992 return wall_bounds;
00993 }
00994
00995 void MapBuilder::getCamBlobs() {
00996 if ( curReq->objectColors[blobDataType].empty() )
00997 return;
00998 cout << "*** Find the blobs ***" << endl;
00999 int minarea;
01000 BlobData::BlobOrientation_t orient;
01001 set<int>& blobColors = curReq->objectColors[blobDataType];
01002
01003
01004 for (set<int>::const_iterator it = blobColors.begin();
01005 it != blobColors.end(); it++) {
01006
01007
01008
01009
01010 minarea = (curReq->minBlobAreas.find(*it)==curReq->minBlobAreas.end()) ?
01011 0 : curReq->minBlobAreas[*it];
01012 orient = (curReq->blobOrientations.find(*it)==curReq->blobOrientations.end()) ?
01013 BlobData::groundplane : curReq->blobOrientations[*it];
01014 vector<Shape<BlobData> > blob_shapes(VRmixin::getBlobsFromRegionGenerator(*it,minarea,orient));
01015 cout << "Found " << blob_shapes.size() << " blobs." << endl;
01016 }
01017 }
01018
01019 }