Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

MarkerData.cc

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #include <iostream>
00003 #include <vector>
00004 #include <map>
00005 
00006 #include "Shared/Config.h"
00007 #include "Motion/Kinematics.h"
00008 #include "SketchSpace.h"
00009 #include "Sketch.h"
00010 #include "ShapeSpace.h"
00011 #include "ShapeRoot.h"
00012 #include "MarkerData.h"
00013 #include "ShapeMarker.h"
00014 #include "VRmixin.h"
00015 
00016 #include "ShapeFuns.h"
00017 #include "visops.h"
00018 #include "BlobData.h"
00019 #include "ShapeBlob.h"
00020 
00021 // only match markers that are less than 5 cm away (this is just the default behavior)
00022 #define MAX_MATCH_DISTANCE 50
00023 
00024 using namespace std;
00025 
00026 namespace DualCoding {
00027 
00028   // initialize dispatch map
00029   const MarkerType_t MarkerData::unknownMarkerType = "unknownMarkerType";
00030 
00031   MarkerData::MarkerData(ShapeSpace& _space, const Point& _center, rgb _rgbvalue) :
00032     BaseData(_space, getStaticType()),
00033     center(_center), typeOfMarker(unknownMarkerType)
00034   { setColor(_rgbvalue); }
00035       
00036   DATASTUFF_CC(MarkerData);
00037 
00038   //! return the centroid of the shape in point format
00039   Point MarkerData::getCentroid() const {
00040     return center;
00041   }
00042   
00043   void MarkerData::printParams() const {
00044     cout << "Type = " << getTypeName() << "  ID=" << getId() << "  ParentID=" << getParentId() << endl;
00045     printf("  color = %d %d %d\n",getColor().red,getColor().green,getColor().blue);
00046     cout << "  center =" << center.coords << endl
00047    << endl;
00048   }
00049 
00050   Sketch<bool>* MarkerData::render() const {
00051     SketchSpace &SkS = space->getDualSpace();
00052     Sketch<bool>* result = new Sketch<bool>(SkS, "render("+getName()+")");
00053     *result = false;
00054 
00055     fmat::Column<3> ctr(center.getCoords());
00056     SkS.applyTmat(ctr);
00057 
00058     const float &cx = ctr[0];
00059     const float &cy = ctr[1];
00060 
00061     // pixel radius
00062     const float rad = 10;
00063     
00064     for (int dx = (int)floor(-rad); dx <= (int)ceil(rad); dx+=1) {
00065       const int yr = (int)sqrt(max((float)0, rad*rad - dx*dx));
00066       for (int dy = -yr; dy <= yr; dy+=1) {
00067   int px = int(cx + dx);
00068   int py = int(cy + dy);
00069 
00070   if ( px >= 0 && px < result->width &&
00071        py >= 0 && py < result->height )
00072     (*result)(px,py) = true;
00073       }
00074     }
00075     
00076     return result;
00077   }
00078 
00079   //! Transformations. (Virtual in BaseData.)
00080   void MarkerData::applyTransform(const fmat::Transform& Tmat, const ReferenceFrameType_t newref) {
00081     center.applyTransform(Tmat,newref);
00082   }
00083 
00084    void MarkerData::projectToGround(const fmat::Transform& camToBase,
00085            const PlaneEquation& groundplane) {   
00086     // transform into camera coordinates using known height of the marker
00087     const float normX = float(2*center.coordX() - VRmixin::camSkS.getWidth()) / VRmixin::camSkS.getWidth();
00088     const float normY = float(2*center.coordY() - VRmixin::camSkS.getHeight()) / VRmixin::camSkS.getWidth();
00089     fmat::Column<3> camera_point;
00090     config->vision.computeRay(normX, normY,
00091             camera_point[0],camera_point[1],camera_point[2]);
00092     // cout << "normX=" << normX << " normY=" << normY << "  camera_point=" << camera_point << endl;
00093     //normalize and multiply by distance to get actual point
00094     float denom = fmat::SubVector<3>(camera_point).norm();
00095     camera_point[0] *= center.coordZ() / denom;
00096     camera_point[1] *= center.coordZ() / denom;
00097     camera_point[2] *= center.coordZ() / denom;
00098     // cout << "denom=" << denom << " camera_point=" << camera_point << endl;
00099     
00100     // transform to base (ground) frame
00101     center.coords = camera_point;
00102     center.applyTransform(camToBase, egocentric);
00103     // cout << "Transform yields: " << center.coords << endl;
00104   }
00105     
00106   void MarkerData::update_derived_properties() {}
00107 
00108   bool MarkerData::isMatchFor(const ShapeRoot& other) const {
00109     if (!isSameTypeAs(other))
00110       return false;
00111     else {
00112       const Shape<MarkerData>& other_marker = ShapeRootTypeConst(other,MarkerData);
00113     
00114       if (!isMatchingMarker(other_marker))
00115   return false;
00116     
00117       float dist = center.distanceFrom(other_marker->center);
00118       return dist < MAX_MATCH_DISTANCE;
00119     }
00120   }
00121 
00122   bool MarkerData::updateParams(const ShapeRoot& other, bool forceUpdate) {
00123     const Shape<MarkerData>& other_marker = ShapeRootTypeConst(other,MarkerData);
00124     int other_conf = other_marker->confidence;
00125     if (other_conf <= 0) {
00126       if (forceUpdate)
00127   other_conf = 1;
00128       else
00129   return false;
00130     }
00131 
00132     const int sumconf = confidence + other_conf;
00133     center = (center*confidence + other_marker->center*other_conf) / sumconf;
00134     confidence += other_conf;
00135 
00136     update_derived_properties();
00137     return true;
00138   }
00139 
00140   bool MarkerData::isMatchingMarker(const Shape<MarkerData>& other) const {
00141     // make sure they are the same marker type
00142     if (!(typeOfMarker == other->typeOfMarker))
00143       return false;
00144   
00145     // make sure colors are the same
00146     if (!(getColor() == other->getColor()))
00147       return false;
00148 
00149     return true;
00150   }
00151 
00152   string MarkerData::getMarkerDescription() const { return ""; }
00153 
00154   string MarkerData::getMarkerTypeName(MarkerType_t type) { return type; }
00155 
00156   vector<Shape<MarkerData> > MarkerData::extractMarkers(const Sketch<uchar> &sketch,
00157               MarkerType_t type,
00158               const MapBuilderRequest &req) {
00159     MarkerExtractFn_t extractor = getExtractorMap()[type];
00160     if (extractor == NULL) {
00161       cout << "Tried to extract markers for unknown marker type '" << type << "'." << endl;
00162       return vector<Shape<MarkerData> >();
00163     }
00164     else
00165       return (*extractor)(sketch,req);
00166   }
00167 
00168   vector<Shape<MarkerData> > MarkerData::extractMarkers(const Sketch<uchar> &sketch, const MapBuilderRequest &req) {
00169     vector<Shape<MarkerData> > markers;
00170     for (map<MarkerType_t, MarkerExtractFn_t>::const_iterator it = getExtractorMap().begin(); it != getExtractorMap().end(); it++)
00171       if (it->second != NULL) {
00172   vector<Shape<MarkerData> > single_type = (*(it->second))(sketch,req);
00173   markers.insert(markers.end(), single_type.begin(), single_type.end());
00174       }
00175   return markers;
00176   }
00177 
00178   void MarkerData::calculateCameraDistance(Point &p, const float assumedHeight) {
00179     // taken from blobdata poster code/some mapbuilder code
00180 #ifdef TGT_HAS_CAMERA
00181     const fmat::Transform camToBase = kine->linkToBase(CameraFrameOffset);
00182 #else
00183     const fmat::Transform camToBase = fmat::Transform::identity();
00184 #endif
00185     // create an elevated plane by shifting the ground plane by assumedHeight
00186     PlaneEquation elevatedPlane = kine->calculateGroundPlane();
00187     // cout << "calculateCameraDistance: ground plane  = " << elevatedPlane << endl;
00188     float const new_displacement = elevatedPlane.getDisplacement() + assumedHeight*elevatedPlane.getZsign();
00189     // cout << "Elevated plane Zsign = " << elevatedPlane.getZsign() << "   new_displacement=" << new_displacement << endl;
00190     elevatedPlane.setDisplacement(new_displacement);
00191     // cout << "calculateCameraDistance:  assumedHeight=" << assumedHeight << "  elevatedPlane=" << elevatedPlane << endl;
00192   
00193     // Project the point onto the elevated plane
00194     Point p2 = p;
00195     p2.projectToGround(camToBase, elevatedPlane);
00196     // See if the point ended up behind the camera.  Must convert back
00197     // to the camera reference frame to do this; can't check sign in
00198     // the base frame because the robot's head could be facing
00199     // backwards.
00200     fmat::Column<3> p3 = camToBase.inverse() * p2.coords;
00201     if ( p3[2] < 0 ) {
00202       cout << "Warning: point " << p << " is above the horizon; cannot project to ground!" << endl;
00203       p2.coords = 1e15f;
00204     }
00205 
00206     // Translate from BaseFrame coordinates back to camera origin.  No need
00207     // for rotation because we're only going to measure distance from the origin
00208     fmat::Column<3> a = camToBase.translation() - p2.coords;
00209 
00210     // Set distance from camera as Z component of camera coordinates
00211     p.setCoords(p.coordX(), p.coordY(), a.norm());
00212     // cout << "  new p=" << p << endl;
00213   }
00214 
00215   MarkerType_t MarkerData::registerMarkerType(std::string markerTypeName, MarkerExtractFn_t extractor) {
00216     if (getExtractorMap()[markerTypeName] != NULL) {
00217       return "";
00218     }
00219     getExtractorMap()[markerTypeName] = extractor;
00220     return markerTypeName;
00221   }
00222 
00223   std::map<MarkerType_t, MarkerExtractFn_t>& MarkerData::getExtractorMap() {
00224     static map<MarkerType_t, MarkerExtractFn_t> extractorMap;
00225     return extractorMap;
00226   }
00227 
00228   const std::set<MarkerType_t> MarkerData::allMarkerTypes() {
00229     std::set<MarkerType_t> result;
00230     for (map<MarkerType_t, MarkerExtractFn_t>::const_iterator it = getExtractorMap().begin(); it != getExtractorMap().end(); it++)
00231       result.insert(it->first);
00232     return result;
00233   }
00234 
00235 } // namespace

DualCoding 5.1CVS
Generated Mon May 9 04:56:26 2016 by Doxygen 1.6.3