Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

NaughtData.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <vector>
00003 #include <list>
00004 #include <math.h>
00005 
00006 #include "SketchSpace.h"
00007 #include "Sketch.h"
00008 #include "Region.h"
00009 #include "visops.h"
00010 
00011 #include "ShapeSpace.h"
00012 #include "ShapeRoot.h"
00013 
00014 #include <DualCoding/NaughtData.h>
00015 #include <DualCoding/ShapeNaught.h>
00016 
00017 #include "Crew/MapBuilder.h"
00018 #include "VRmixin.h"
00019 
00020 
00021 using namespace std;
00022 
00023 namespace DualCoding {
00024 
00025 DATASTUFF_CC(NaughtData);
00026 
00027 NaughtData::NaughtData(ShapeSpace& _space, const Point& _centroid, float _height, float _radius) :
00028   BaseData(_space, getStaticType()), centroid(_centroid), height(_height), radius(_radius) {}
00029 
00030 bool NaughtData::isMatchFor(const ShapeRoot& other) const {
00031   if (!(isSameTypeAs(other) && isSameColorAs(other)))
00032     return false;
00033   
00034   const Shape<NaughtData>& otherCyl = ShapeRootTypeConst(other,NaughtData);
00035   
00036   float diff = (centroid - otherCyl->centroid).xyzNorm();
00037   //if (diff < 2*radius && fabs(radius - otherCyl->radius) < radius/2)
00038   if (diff < 3*radius && fabs(radius - otherCyl->radius) < radius*0.8) // *** quick fix for Tapia
00039     return true;
00040   else
00041     return false;
00042 }
00043 
00044 bool NaughtData::updateParams(const ShapeRoot& other, bool) {
00045   const Shape<NaughtData>& other_naught = ShapeRootTypeConst(other,NaughtData);
00046   if (other_naught->confidence <= 0)
00047     return false;
00048   const int other_conf = other_naught->confidence;
00049   centroid = (centroid*confidence + other_naught->getCentroid()*other_conf) / (confidence+other_conf);
00050   radius = (radius*confidence + other_naught->getRadius()*other_conf) / (confidence+other_conf);
00051   height = (height*confidence + other_naught->getHeight()*other_conf) / (confidence+other_conf);
00052   return true;
00053 }
00054 
00055 void NaughtData::printParams() const {
00056   cout << "Type = " << getTypeName() << "  ID=" << getId() << "  ParentID=" << getParentId() << endl;
00057   printf("  color = %d %d %d\n",getColor().red,getColor().green,getColor().blue);
00058   cout << "  centroid = " << centroid << endl;
00059   cout << "  radius = " << radius << endl;
00060   cout << "  height = " << height << endl;
00061 }
00062 
00063 void NaughtData::applyTransform(const fmat::Transform& Tmat, const ReferenceFrameType_t newref) {
00064   centroid.applyTransform(Tmat, newref);
00065 }
00066 
00067 void NaughtData::projectToGround(const fmat::Transform& camToBase, const PlaneEquation& groundplane) {
00068   PlaneEquation raisedGroundPlane(groundplane);
00069   raisedGroundPlane.setDisplacement(groundplane.getDisplacement() + height);
00070   centroid.projectToGround(camToBase, raisedGroundPlane);
00071 }
00072 
00073 // Extract Naught similar to the ellipse by finding a region, checking to see if its of the 
00074 // appropriate shape to be a Naught and then creating said naught
00075 std::vector<Shape<NaughtData> > NaughtData::extractNaughts(const Sketch<bool> &sketch, 
00076                                                            const fmat::Column<3>& dimensions) {
00077   NEW_SKETCH_N(labels,uint,visops::oldlabelcc(sketch,visops::EightWayConnect));
00078   const int REGION_THRESH = 25;  // ignore regions smaller than this
00079   list<Region> regionlist = Region::extractRegions(labels,REGION_THRESH);
00080   std::vector<Shape<NaughtData> > naughts;
00081 
00082   // A naught is accepted if the number of pixels in the outer 2/3 is
00083   // 5 times greater than the number in the inner 1/3, and if the
00084   // two sums along each semi-axis are relatively equal to each other.
00085   for ( Region reg : regionlist ) {
00086     Point center = reg.findCentroid();
00087     float semimaj = reg.findSemiMajorAxisLength();
00088     float semimin = reg.findSemiMinorAxisLength();
00089     float orient = reg.findPrincipalAxisOrientation();
00090     float tcos = cos(orient), tsin = sin(orient);
00091     float majthird = semimaj / 3, minthird = semimin / 3;
00092     int counts[4][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
00093     for ( float r = 0; r < semimaj+1; r++ ) {
00094       float x1 = center.coordX() + r * tcos;
00095       float y1 = center.coordY() + r * tsin;
00096       float x2 = center.coordX() - r * tcos;
00097       float y2 = center.coordY() - r * tsin;
00098       if ( x1 >= 0 && x1 < sketch.width && y1 >= 0 && y1 < sketch.height )
00099         counts[0][int(r/majthird)] += sketch(x1,y1);
00100       if ( x2 >= 0 && x2 < sketch.width && y2 >= 0 && y2 < sketch.height )
00101         counts[1][int(r/majthird)] += sketch(x2,y2);
00102     }
00103     for ( float r = 0; r < semimin+1; r++ ) {
00104       float x3 = center.coordX() + r * tsin;
00105       float y3 = center.coordY() + r * tcos;
00106       float x4 = center.coordX() - r * tsin;
00107       float y4 = center.coordY() - r * tcos;
00108       if ( x3 >= 0 && x3 < sketch.width && y3 >= 0 && y3 < sketch.height )
00109         counts[2][int(r/minthird)] += sketch(x3,y3);
00110       if ( x4 >= 0 && x4 < sketch.width && y4 >= 0 && y4 < sketch.height )
00111         counts[3][int(r/minthird)] += sketch(x4,y4);
00112     }
00113     // cout << " centroid=" << reg.findCentroid() << " area=" << reg.findArea() 
00114     //     << " semimaj=" << semimaj << " semimin=" << semimin << " counts ";
00115     bool good = true;
00116     int sums[4];
00117     for ( int i = 0; i<4; i++ ) {
00118       sums[i] = counts[i][1] + counts[i][2];
00119       if ( ! (sums[i] > 5*counts[i][0] && sums[i] >= 2) )
00120         good = false;
00121       sums[i] += 5; // so ratios computed below aren't too sensitive to small counts
00122       // for ( int j=0; j<3; j++ )
00123       //  cout << " " << counts[i][j];
00124       // cout << " / ";
00125     }
00126     // now check the ratios of sums to make sure the shape is reasonably symmetric
00127     if ( float(min(sums[0],sums[1])) / max(sums[0],sums[1]) < 0.8 ||
00128          float(min(sums[2],sums[3])) / max(sums[2],sums[3]) < 0.8 )
00129       good = false;
00130     if ( good ) {   // all tests passed
00131       Shape<NaughtData> temp_naught(reg, dimensions[2]); 
00132       temp_naught->setParentId(sketch->getViewableId());
00133       temp_naught->setColor(sketch->getColor());
00134       naughts.push_back(Shape<NaughtData>(temp_naught));
00135     }
00136   }
00137   return naughts;
00138 }
00139 
00140 Sketch<bool>* NaughtData::render() const {
00141   SketchSpace &SkS = space->getDualSpace();
00142   fmat::Column<3> ctr(centroid.getCoords());
00143   SkS.applyTmat(ctr);
00144   const float &cx = ctr[0];
00145   const float &cy = ctr[1];
00146   fmat::Column<3> rad = fmat::pack(radius,0,0);
00147   SkS.applyTmat(rad);
00148   const float &scaledRadius = fabs(rad[0]);
00149   Sketch<bool>* result = new Sketch<bool>(SkS, "render("+getName()+")");
00150   (*result)->inheritFrom(*this);
00151   *result = 0;
00152   for ( float dx=-scaledRadius; dx<=scaledRadius; dx+=0.2 ) {
00153     float dy = sqrt(scaledRadius*scaledRadius - dx*dx);
00154       int const px = round(cx + dx);
00155       int const py1 = round(cy - dy);
00156       int const py2 = round(cy + dy);
00157       if ( px >= 0 && px < result->width) {
00158         if ( py1 >= 0 && py1 < result->height )
00159           (*result)(px,py1) = true;
00160         if ( py2 >= 0 && py2 < result->height )
00161           (*result)(px,py2) = true;
00162       }
00163   }
00164   return result;
00165 }
00166 
00167 } // namespace

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