MarkerData.cc
Go to the documentation of this file.00001
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
00022 #define MAX_MATCH_DISTANCE 50
00023
00024 using namespace std;
00025
00026 namespace DualCoding {
00027
00028
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
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
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
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
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
00093
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
00099
00100
00101 center.coords = camera_point;
00102 center.applyTransform(camToBase, egocentric);
00103
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
00142 if (!(typeOfMarker == other->typeOfMarker))
00143 return false;
00144
00145
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
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
00186 PlaneEquation elevatedPlane = kine->calculateGroundPlane();
00187
00188 float const new_displacement = elevatedPlane.getDisplacement() + assumedHeight*elevatedPlane.getZsign();
00189
00190 elevatedPlane.setDisplacement(new_displacement);
00191
00192
00193
00194 Point p2 = p;
00195 p2.projectToGround(camToBase, elevatedPlane);
00196
00197
00198
00199
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
00207
00208 fmat::Column<3> a = camToBase.translation() - p2.coords;
00209
00210
00211 p.setCoords(p.coordX(), p.coordY(), a.norm());
00212
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 }