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
00038 if (diff < 3*radius && fabs(radius - otherCyl->radius) < radius*0.8)
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
00074
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;
00079 list<Region> regionlist = Region::extractRegions(labels,REGION_THRESH);
00080 std::vector<Shape<NaughtData> > naughts;
00081
00082
00083
00084
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
00114
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;
00122
00123
00124
00125 }
00126
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 ) {
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 }