00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 #include "CannyModel.H"
00039 #include "Image/DrawOps.H"
00040 #include "Image/ColorOps.H"
00041 #include "GUI/XWindow.H"
00042 #include <cmath>
00043 
00044 
00045 ShapeModel::ShapeModel(const int ndims, const double thresh,
00046                        double* dims, const bool debug) :
00047   itsNumDims(ndims), itsThreshold(thresh),
00048   itsDebugMode(debug), itsWindow()
00049 {
00050 
00051   itsDimensions = (double*)calloc(ndims+1, sizeof(double));
00052   for(int i = 0; i <=ndims; i++){
00053 
00054     itsDimensions[i] = dims[i];
00055   }
00056 
00057 }
00058 
00059 
00060 ShapeModel::~ShapeModel()
00061 {
00062   itsWindow.reset(NULL);
00063 }
00064 
00065 
00066 double ShapeModel::getThreshold() const
00067 { return itsThreshold; }
00068 
00069 
00070 int ShapeModel::getNumDims() const
00071 { return itsNumDims; }
00072 
00073 double* ShapeModel::getDimensions() const
00074 {
00075   double* tempDims = (double*)calloc(itsNumDims+1, sizeof(double));
00076   for(int i = 0; i < itsNumDims; i++){
00077     tempDims[i] = itsDimensions[i];
00078   }
00079 
00080   return itsDimensions;
00081 }
00082 
00083 void ShapeModel::setDimensions(double* in)
00084 {
00085   for(int i = 0; i <=itsNumDims; i++){
00086     itsDimensions[i] = in[i];
00087   }
00088 }
00089 
00090 
00091 float ShapeModel::getDistVal(const double x, const double y,
00092                              const Image<float>& distMap,
00093                              Image< PixRGB<byte> >& xdisp) const
00094 {
00095   int xx = int(x + 0.5), yy = int(y + 0.5);
00096 
00097   
00098   
00099   if (distMap.coordsOk(int(x), int(y)))
00100     {
00101       if (xdisp.initialized())
00102         drawDisk(xdisp, Point2D<int>(xx, yy), 3, PixRGB<byte>(255, 0, 0));
00103       float d = distMap.getValInterp(x, y);
00104       return d * d;
00105     }
00106   else
00107     {
00108       
00109       
00110       int xerror = 0, yerror = 0;
00111       if (xx < 0) xerror = -xx;
00112       else if (xx >= distMap.getWidth()) xerror = xx - distMap.getWidth();
00113 
00114       if (yy < 0) yerror = -yy;
00115       else if (yy > distMap.getHeight()) yerror = yy - distMap.getHeight();
00116 
00117       return 10.0f * ((xerror + yerror) * (xerror + yerror));
00118     }
00119 }
00120 
00121 
00122 double ShapeModel::calcDist(double p[], const Image<float>& distMap) const
00123 {
00124 
00125   
00126   Image< PixRGB<byte> > xdisp;
00127   xdisp = toRGB(Image<byte>(distMap));
00128 
00129   
00130   
00131   if (itsWindow.get() == NULL && itsDebugMode == true){
00132     const_cast<ShapeModel *>(this)->
00133       itsWindow.reset(new XWindow(distMap.getDims()));
00134     const_cast<ShapeModel *>(this)->
00135       itsWindow->setPosition((xdisp.getWidth()*2)+20, 0);
00136   }
00137 
00138   
00139   double dist = getDist(p, distMap, xdisp);
00140 
00141   
00142   if (itsWindow.get()){
00143     itsWindow->drawImage(xdisp);
00144   }
00145   return dist;
00146 }
00147 
00148 
00149 RectangleShape::RectangleShape(const double thresh, double* dims, const bool debug) :
00150   ShapeModel(5, thresh, dims, debug)
00151 {  }
00152 
00153 
00154 RectangleShape::~RectangleShape()
00155 { }
00156 
00157 
00158 float RectangleShape::getDist(double p[], const Image<float>& distMap,
00159                               Image< PixRGB<byte> >& xdisp) const
00160 {
00161   
00162 
00163   
00164   double x_center = p[1];
00165   double y_center = p[2];
00166   double alpha = p[3];
00167 
00168   double width = p[4];
00169   double height = p[5];
00170 
00171   
00172   float sina = sin(alpha/10.0);
00173   float cosa = cos(alpha/10.0);
00174   int numPts = 0;
00175   float dist = 0.0;
00176 
00177   
00178   for (int i = -5; i < 5; i++) {
00179     
00180     float tempValX = x_center - width*cosa/2.0 - (i+1)*height*sina/10.0;
00181     float tempValY = y_center - width*sina/2.0 + (i+1)*height*cosa/10.0;
00182     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00183     numPts++;
00184 
00185     
00186     tempValX = x_center + width*cosa/2.0 - (i+1)*height*sina/10.0;
00187     tempValY = y_center + width*sina/2.0 + (i+1)*height*cosa/10.0;
00188     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00189     numPts++;
00190 
00191     
00192     tempValX = x_center + height*sina/2.0 + (i+1)*width*cosa/10.0;
00193     tempValY = y_center - height*cosa/2.0 + (i+1)*width*sina/10.0;
00194     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00195     numPts++;
00196 
00197     
00198     tempValX = x_center - height*sina/2.0 + (i+1)*width*cosa/10.0;
00199     tempValY = y_center + height*cosa/2.0 + (i+1)*width*sina/10.0;
00200     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00201     numPts++;
00202   }
00203 
00204   dist = dist / numPts;
00205 
00206   
00207   if (width < 40) dist += (10.0*((40 - width) * (40 - width)));
00208   if (height < 30) dist += (10.0*((30 - height) * (30-height)));
00209 
00210   return dist;
00211 }
00212 
00213 
00214 
00215 SquareShape::SquareShape(const double thresh, double* dims, const bool debug) :
00216   ShapeModel(4, thresh, dims, debug)
00217 {  }
00218 
00219 
00220 SquareShape::~SquareShape()
00221 { }
00222 
00223 
00224 float SquareShape::getDist(double p[], const Image<float>& distMap,
00225                               Image< PixRGB<byte> >& xdisp) const
00226 {
00227   
00228   double x_center = p[1];
00229   double y_center = p[2];
00230   double alpha = p[4];
00231   double height = p[3];
00232 
00233   
00234   float sina = sin(alpha/10.0);
00235   float cosa = cos(alpha/10.0);
00236   int numPts = 0;
00237   float dist = 0.0;
00238 
00239   
00240   for(int i=-5; i<5; i++) {
00241     
00242     float tempValX = x_center - height*cosa/2 - (i+1)*height*sina/10;
00243     float tempValY = y_center - height*sina/2 + (i+1)*height*cosa/10;
00244     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00245     numPts++;
00246 
00247     
00248     tempValX = x_center + height*cosa/2 - (i+1)*height*sina/10;
00249     tempValY = y_center + height*sina/2 + (i+1)*height*cosa/10;
00250     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00251     numPts++;
00252 
00253     
00254     tempValX = x_center + height*sina/2 + (i+1)*height*cosa/10;
00255     tempValY = y_center - height*cosa/2 + (i+1)*height*sina/10;
00256     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00257     numPts++;
00258 
00259     
00260     tempValX = x_center - height*sina/2 + (i+1)*height*cosa/10;
00261     tempValY = y_center + height*cosa/2 + (i+1)*height*sina/10;
00262     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00263     numPts++;
00264   }
00265 
00266   dist = dist / numPts;
00267 
00268   
00269   if (height < 30) dist += (10.0 * ((30 - height)*(30 - height)));
00270 
00271   return dist;
00272 }
00273 
00274 
00275 
00276 
00277 OctagonShape::OctagonShape(const double thresh, double* dims, const bool debug) :
00278   ShapeModel(4, thresh, dims, debug)
00279 {  }
00280 
00281 
00282 OctagonShape::~OctagonShape()
00283 { }
00284 
00285 
00286 float OctagonShape::getDist(double p[], const Image<float>& distMap,
00287                               Image< PixRGB<byte> >& xdisp) const
00288 {
00289   
00290   double x_center = p[1];
00291   double y_center = p[2];
00292   double alpha = p[4];
00293   double height = p[3]; 
00294 
00295   
00296   float sina = sin(alpha/10.0);
00297   float cosa = cos(alpha/10.0);
00298   
00299   float sinb = sin((alpha+40.00)/10.0);
00300   float cosb = cos((alpha+40.00)/10.0);
00301   int numPts = 0;
00302   float dist = 0.0;
00303 
00304 
00305   
00306   for(int i=-5; i<5; i++) {
00307       
00308       
00309       float tempValX = x_center - height*cosa/2 - ((i+1)*height*sina/10)/2.2;
00310       float tempValY = y_center - height*sina/2 + ((i+1)*height*cosa/10)/2.2;
00311       dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00312       numPts++;
00313 
00314       
00315       tempValX = x_center - height*cosb/2 - ((i+1)*height*sinb/10)/2.2;
00316       tempValY = y_center - height*sinb/2 + ((i+1)*height*cosb/10)/2.2;
00317       dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00318       numPts++;
00319 
00320       
00321       tempValX = x_center + height*cosa/2 - ((i+1)*height*sina/10)/2.2;
00322       tempValY = y_center + height*sina/2 + ((i+1)*height*cosa/10)/2.2;
00323       dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00324       numPts++;
00325 
00326       
00327       tempValX = x_center + height*cosb/2 - ((i+1)*height*sinb/10)/2.2;
00328       tempValY = y_center + height*sinb/2 + ((i+1)*height*cosb/10)/2.2;
00329       dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00330       numPts++;
00331 
00332       
00333       tempValX = x_center + height*sina/2 + ((i+1)*height*cosa/10)/2.2;
00334       tempValY = y_center - height*cosa/2 + ((i+1)*height*sina/10)/2.2;
00335       dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00336       numPts++;
00337 
00338       
00339       tempValX = x_center + height*sinb/2 + ((i+1)*height*cosb/10)/2.2;
00340       tempValY = y_center - height*cosb/2 + ((i+1)*height*sinb/10)/2.2;
00341       dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00342       numPts++;
00343 
00344       
00345       tempValX = x_center - height*sina/2 + ((i+1)*height*cosa/10)/2.2;
00346       tempValY = y_center + height*cosa/2 + ((i+1)*height*sina/10)/2.2;
00347       dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00348       numPts++;
00349 
00350       
00351       tempValX = x_center - height*sinb/2 + ((i+1)*height*cosb/10)/2.2;
00352       tempValY = y_center + height*cosb/2 + ((i+1)*height*sinb/10)/2.2;
00353       dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00354       numPts++;
00355     }
00356 
00357   dist = dist / numPts;
00358 
00359   
00360   if (height < 20) dist += (10.0 * ((20 - height) * (20 - height)));
00361 
00362   return dist;
00363 }
00364 
00365 
00366 
00367 
00368 CircleShape::CircleShape(const double thresh, double* dims, const bool debug) :
00369   ShapeModel(3, thresh, dims, debug)
00370 {  }
00371 
00372 
00373 CircleShape::~CircleShape()
00374 { }
00375 
00376 
00377 float CircleShape::getDist(double p[], const Image<float>& distMap,
00378                               Image< PixRGB<byte> >& xdisp) const
00379 {
00380   
00381   double x_center = p[1];
00382   double y_center = p[2];
00383   double radius = p[3];
00384 
00385   
00386   int numPts = 0;
00387   float dist = 0.0;
00388 
00389 
00390   
00391   for(int i=-7; i<7; i++) {
00392     
00393     float tempValX = x_center + radius * cos(i*2*M_PI/14);
00394     float tempValY = y_center + radius * sin(i*2*M_PI/14);
00395     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00396     numPts++;
00397   }
00398 
00399   dist = dist / numPts;
00400 
00401   
00402   if (radius < 20) dist += (10.0 * ((20 - radius) * (20 - radius)));
00403 
00404   return dist;
00405 }
00406 
00407 
00408 
00409 
00410 ParallelShape::ParallelShape(const double thresh, double* dims, const bool debug) :
00411   ShapeModel(5, thresh, dims, debug)
00412 {  }
00413 
00414 
00415 ParallelShape::~ParallelShape()
00416 { }
00417 
00418 
00419 float ParallelShape::getDist(double p[], const Image<float>& distMap,
00420                               Image< PixRGB<byte> >& xdisp) const
00421 {
00422 
00423   
00424   double x_center = p[1];
00425   double y_center = p[2];
00426   double alpha = p[3];
00427 
00428   double width = p[4];
00429   double height = p[5];
00430 
00431   
00432   float sina = sin(alpha/10.0);
00433   float cosa = cos(alpha/10.0);
00434   int numPts = 0;
00435   float dist = 0.0;
00436 
00437   
00438   for (int i = -5; i < 5; i++) {
00439 
00440     
00441     float tempValX = x_center + height*sina/2.0 + (i+1)*width*cosa/10.0;
00442     float tempValY = y_center - height*cosa/2.0 + (i+1)*width*sina/10.0;
00443     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00444     numPts++;
00445 
00446     
00447     tempValX = x_center - height*sina/2.0 + (i+1)*width*cosa/10.0;
00448     tempValY = y_center + height*cosa/2.0 + (i+1)*width*sina/10.0;
00449     dist += getDistVal(tempValX, tempValY, distMap, xdisp);
00450     numPts++;
00451   }
00452 
00453   dist = dist / numPts;
00454 
00455   
00456   if (width < 70) dist += (10.0 * ((70 - width) * (70-width)));
00457   if (height < 30) dist += (10.0 * ((30 - height) * (30 - height)));
00458 
00459   return dist;
00460 }
00461 
00462 
00463 
00464 
00465