Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

TagDetection.cc

Go to the documentation of this file.
00001 #include "TagDetection.h"
00002 #include "MathUtil.h"
00003 #include "Shared/mathutils.h" // for isnan fix
00004 
00005 namespace AprilTags {
00006 
00007 TagDetection::TagDetection() 
00008   : good(false), obsCode(), code(), id(), hammingDistance(), rotation(), p(),
00009     cxy(), observedPerimeter(), homography(), hxy() {}
00010 
00011 TagDetection::TagDetection(int _id)
00012   : good(false), obsCode(), code(), id(_id), hammingDistance(), rotation(), p(),
00013     cxy(), observedPerimeter(), homography(), hxy() {}
00014 
00015 AngSignPi TagDetection::getXYOrientation() const {
00016   // Because the order of segments in a quad is arbitrary, so is the
00017   // homography's rotation, so we can't determine orientation directly
00018   // from the homography.  Instead, use the homography to find two
00019   // bottom corners of a properly oriented tag in pixel coordinates,
00020   // and then compute orientation from that.
00021   std::pair<float,float> p0 = interpolate(-1,-1);   // lower left corner of tag
00022   std::pair<float,float> p1 = interpolate(1,-1);    // lower right corner of tag
00023   AngSignPi orient = std::atan2(p1.second - p0.second, p1.first - p0.first);
00024   return ! std::isnan(float(orient)) ? orient : AngSignPi(0);
00025 }
00026 
00027 std::pair<float,float> TagDetection::interpolate(float x, float y) const {
00028   float z = homography(2,0)*x + homography(2,1)*y + homography(2,2);
00029   if ( z == 0 )
00030     return std::pair<float,float>(0,0);  // prevents returning a pair with a -NaN, for which gcc 4.4 flubs isnan
00031   float newx = (homography(0,0)*x + homography(0,1)*y + homography(0,2))/z + hxy.first;
00032   float newy = (homography(1,0)*x + homography(1,1)*y + homography(1,2))/z + hxy.second;
00033   return std::pair<float,float>(newx,newy);
00034 }
00035 
00036 bool TagDetection::overlapsTooMuch(const TagDetection &other) const {
00037   // Compute a sort of "radius" of the two targets. We'll do this by
00038   // computing the average length of the edges of the quads (in
00039   // pixels).
00040   float radius =
00041     ( MathUtil::distance2D(p[0], p[1]) +
00042       MathUtil::distance2D(p[1], p[2]) +
00043       MathUtil::distance2D(p[2], p[3]) +
00044       MathUtil::distance2D(p[3], p[0]) +
00045       MathUtil::distance2D(other.p[0], other.p[1]) +
00046       MathUtil::distance2D(other.p[1], other.p[2]) +
00047       MathUtil::distance2D(other.p[2], other.p[3]) +
00048       MathUtil::distance2D(other.p[3], other.p[0]) ) / 16.0f;
00049 
00050   // distance (in pixels) between two tag centers
00051   float dist = MathUtil::distance2D(cxy, other.cxy);
00052 
00053   // reject pairs where the distance between centroids is smaller than
00054   // the "radius" of one of the tags.
00055   return ( dist < radius );
00056 }
00057 
00058 } // namespace

Tekkotsu v5.1CVS
Generated Fri Mar 16 05:26:53 2012 by Doxygen 1.6.3