Homepage Demos Overview Downloads Tutorials Reference
Credits

EllipseData.cc

Go to the documentation of this file.
00001 //-*-c++-*-
00002 #include <iostream>
00003 #include <vector>
00004 #include <list>
00005 #include <math.h>
00006 
00007 #include "BaseData.h"    // superclass
00008 #include "Point.h"       // Point data member
00009 #include "Measures.h"    // coordinate_t; AngPi data member
00010 #include "ShapeTypes.h"  // ellipseDataType
00011 
00012 #include "SketchSpace.h"
00013 #include "Sketch.h"
00014 #include "Region.h"
00015 #include "visops.h"
00016 
00017 #include "ShapeSpace.h"  // required by DATASTUFF_CC
00018 #include "ShapeRoot.h"   // required by DATASTUFF_CC
00019 
00020 #include "EllipseData.h"
00021 #include "ShapeEllipse.h"
00022 
00023 namespace DualCoding {
00024 
00025 inline int round(float x) { return (int) ceil((double)x-0.5f); }
00026 
00027 EllipseData::EllipseData(ShapeSpace& _space, const Point &c) 
00028   : BaseData(_space, getStaticType()),
00029     center_pt(c), semimajor(0), semiminor(0), orientation(0)
00030 { center_pt.setRefFrameType(getRefFrameType());
00031   mobile = ELLIPSE_DATA_MOBILE; }
00032   
00033 DATASTUFF_CC(EllipseData);
00034 
00035 BoundingBox EllipseData::getBoundingBox() const {
00036   float o_sin = sin(orientation);
00037   float o_cos = cos(orientation);
00038   Point major_tip(semimajor*o_cos, semimajor*o_sin);
00039   Point minor_tip(-semiminor*o_sin, semiminor*o_cos);
00040   return BoundingBox(BoundingBox(BoundingBox(center_pt+major_tip),
00041          BoundingBox(center_pt-major_tip)),
00042          BoundingBox(BoundingBox(center_pt+minor_tip),
00043          BoundingBox(center_pt-minor_tip)));
00044 }
00045 
00046 bool EllipseData::isMatchFor(const ShapeRoot& other) const {
00047   if (!(isSameTypeAs(other) && isSameColorAs(other)))
00048     return false;
00049   const Shape<EllipseData>& other_ellipse = ShapeRootTypeConst(other,EllipseData);
00050   float dist = center_pt.distanceFrom(other_ellipse->centerPt());
00051   return dist < 2*max(semimajor,other_ellipse->semimajor); // *** DST hack
00052 }
00053 
00054 bool EllipseData::updateParams(const ShapeRoot& other, bool) {
00055   const Shape<EllipseData>& other_ellipse = ShapeRootTypeConst(other,EllipseData);
00056   if (other_ellipse->confidence <= 0)
00057     return false;
00058   const int other_conf = other_ellipse->confidence;
00059   center_pt = (center_pt*confidence + other_ellipse->centerPt()*other_conf) / (confidence+other_conf);
00060   semimajor = (semimajor*confidence + other_ellipse->getSemimajor()*other_conf) / (confidence+other_conf);
00061   semiminor = (semiminor*confidence + other_ellipse->getSemiminor()*other_conf) / (confidence+other_conf);
00062   orientation = orientation*((orientation_t)confidence/(confidence+other_conf))
00063     + other_ellipse->getOrientation()*((orientation_t)confidence/(confidence+other_conf));
00064   return true;
00065 }
00066 
00067 //! Print information about this shape. (Virtual in BaseData.)
00068 void
00069 EllipseData::printParams() const {
00070   cout << "Type = " << getTypeName();
00071   cout << "Shape ID = " << getId() << endl;
00072   cout << "Parent ID = " << getParentId() << endl;
00073   
00074   // Print critical points.
00075   cout << endl;
00076   cout << "center{" << centerPt().coordX() << ", " << centerPt().coordY() << "}" << endl;
00077   
00078   cout << "semimajor = " << getSemimajor() << endl;
00079   cout << "semiminor = " << getSemiminor() << endl;
00080   cout << "orientation = " << getOrientation() << endl;
00081   printf("color = %d %d %d\n",getColor().red,getColor().green,getColor().blue);
00082   cout << "mobile = " << isMobile() << endl;
00083   cout << "viewable = " << isViewable() << endl;
00084 }
00085 
00086 pair<Point,Point> EllipseData::findFeaturePoints() const {
00087   AngPi theta = getOrientation();
00088   NEWMAT::ColumnVector from_center(4);
00089 
00090   float dl = getSemimajor();
00091   from_center << dl*cos(theta) << dl*sin(theta) << 0 << 0;
00092   Point majorPt(from_center);
00093   majorPt += center_pt;
00094 
00095   dl = getSemiminor();
00096   theta = theta + (AngPi) (M_PI/2);
00097   from_center << dl*sin(theta) << dl*cos(theta) << 0 << 0;
00098   Point minorPt(from_center);
00099   minorPt += center_pt;
00100   return pair<Point,Point>(majorPt,minorPt);
00101 }
00102 
00103 //! Transformations. (Virtual in BaseData.)
00104 void EllipseData::applyTransform(const NEWMAT::Matrix& Tmat) {
00105   pair<Point,Point> featurePts = findFeaturePoints();
00106   center_pt.applyTransform(Tmat);
00107   //  orientation = orientation - (AngTwoPi)atan2(Tmat(1,2),Tmat(1,1));
00108   featurePts.first.applyTransform(Tmat);
00109   featurePts.second.applyTransform(Tmat);
00110   updateProperties(featurePts.first, featurePts.second);
00111 }
00112 
00113 void EllipseData::updateProperties(const Point& majorPt, const Point& minorPt) {
00114   setSemiminor(minorPt.xyDistanceFrom(center_pt));
00115   setSemimajor(majorPt.xyDistanceFrom(center_pt));
00116   setOrientation(atan2(majorPt.coords(2)-center_pt.coords(2),majorPt.coords(1)-center_pt.coords(1)));
00117 }
00118 
00119 void EllipseData::projectToGround(const NEWMAT::Matrix& camToBase,
00120           const NEWMAT::ColumnVector& groundplane) {
00121   pair<Point,Point> featurePts = findFeaturePoints();
00122   center_pt.projectToGround(camToBase,groundplane);
00123   featurePts.first.projectToGround(camToBase,groundplane);  
00124   featurePts.second.projectToGround(camToBase,groundplane);
00125   updateProperties(featurePts.first, featurePts.second);
00126 }
00127 
00128 //! Functions to set properties.
00129 //{
00130 void EllipseData::setOrientation(const AngPi _orientation) {
00131   orientation = AngPi(_orientation);
00132   deleteRendering();
00133 }
00134 
00135 void EllipseData::setSemimajor(float _semimajor) {
00136   semimajor = _semimajor;
00137   deleteRendering();
00138 }
00139 
00140 void EllipseData::setSemiminor(float _semiminor) {
00141   semiminor = _semiminor;
00142   deleteRendering();
00143 }
00144 //}
00145 
00146 
00147 // ==================================================
00148 // BEGIN SKETCH MANIPULATION AND LINE EXTRACTION CODE
00149 // ==================================================
00150 
00151 
00152 //! Ellipse extraction.
00153 
00154 std::vector<Shape<EllipseData> > EllipseData::extractEllipses(const Sketch<bool>& sketch)
00155 {
00156   const float AREA_TOLERANCE = 0.5;
00157   const int REGION_THRESH = 25;
00158   NEW_SKETCH_N(labels,usint,visops::oldlabelcc(sketch,visops::EightWayConnect));
00159   list<Region> regionlist = Region::extractRegions(labels,REGION_THRESH);
00160   std::vector<Shape<EllipseData> > ellipses;
00161   
00162   if(regionlist.empty())
00163     return ellipses;
00164   
00165   typedef list<Region>::iterator R_IT;
00166   for (R_IT it = regionlist.begin(); it != regionlist.end(); ++it) {
00167     float ratio = it->findSemiMajorAxisLength()/(float)(it->findSemiMinorAxisLength());
00168     if((ratio < 2.0) && (ratio > 1.0/(float)2.0)
00169        && (it->findArea() > M_PI*2.0*(it->findSemiMajorAxisLength())
00170      *2.0*(it->findSemiMinorAxisLength())*AREA_TOLERANCE/4.0)) {
00171       Shape<EllipseData> temp_ellipse(*it);
00172       temp_ellipse->setParentId(sketch->getViewableId());
00173       temp_ellipse->setColor(sketch->getColor());
00174       ellipses.push_back(Shape<EllipseData>(temp_ellipse));
00175     };
00176   }
00177   return ellipses;
00178 }
00179 
00180 
00181 //! Render into a sketch space and return reference. (Private.)
00182 Sketch<bool>* EllipseData::render() const {
00183   SketchSpace &SkS = space->getDualSpace();
00184   NEWMAT::ColumnVector ctr(centerPt().getCoords());
00185   SkS.applyTmat(ctr);
00186   const float &cx = ctr(1);
00187   const float &cy = ctr(2);
00188   const NEWMAT::Matrix &Tmat = SkS.getTmat();
00189   NEWMAT::ColumnVector ori(2);
00190   ori << cos(orientation) << sin(orientation);
00191   NEWMAT::Matrix rot(2,2);
00192   rot(1,1) = Tmat(1,1);
00193   rot(1,2) = Tmat(1,2);
00194   rot(2,1) = Tmat(2,1);
00195   rot(2,2) = Tmat(2,2);
00196   ori = rot * ori;
00197   const float &cosT = ori(1);
00198   const float &sinT = ori(2);
00199   const float xRange = semimajor / Tmat(4,4);
00200   const float majorSq = xRange*xRange;
00201   const float mnrDevMjr = semiminor/semimajor;
00202   Sketch<bool> result(SkS, "render("+getName()+")");
00203   result = 0;
00204   for (float xDist = -xRange; xDist <= xRange; xDist+=0.2) {
00205     const float yRange = sqrt(max((float)0, majorSq - xDist*xDist)) * mnrDevMjr;
00206     for (float yDist = -yRange; yDist <= yRange; yDist+=0.2) {
00207       int const px = round(cx+xDist*cosT-yDist*sinT);
00208       int const py = round(cy+yDist*cosT+xDist*sinT);
00209       if ( px >= 0 && px < result.width &&
00210      py >= 0 && py < result.height )
00211   result(px,py) = true;
00212     }
00213   }
00214   return new Sketch<bool>(result);
00215 }
00216 
00217 } // namespace

DualCoding 3.0beta
Generated Wed Oct 4 00:01:53 2006 by Doxygen 1.4.7