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