latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2004, 2005, 2006 00003 * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany 00004 * 00005 * This file is part of the LTI-Computer Vision Library (LTI-Lib) 00006 * 00007 * The LTI-Lib is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License (LGPL) 00009 * as published by the Free Software Foundation; either version 2.1 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * The LTI-Lib is distributed in the hope that it will be 00013 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00014 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with the LTI-Lib; see the file LICENSE. If 00019 * not, write to the Free Software Foundation, Inc., 59 Temple Place - 00020 * Suite 330, Boston, MA 02111-1307, USA. 00021 */ 00022 00023 00024 /*-------------------------------------------------------------------- 00025 * project ....: LTI-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiFastEllipseExtraction.h 00027 * authors ....: Ingo Grothues (ingo@isdevelop.de) 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 23.4.2004 00030 * revisions ..: $Id: ltiFastEllipseExtraction.h,v 1.8 2006/08/25 15:33:39 doerfler Exp $ 00031 */ 00032 00033 #ifndef _LTI_FAST_ELLIPSE_EXTRACTION_H_ 00034 #define _LTI_FAST_ELLIPSE_EXTRACTION_H_ 00035 00036 #include "ltiFeatureExtractor.h" 00037 #include "ltiPoint.h" 00038 #include <vector> 00039 00040 namespace lti { 00041 00042 /** 00043 * This functor implements a fast ellipse extraction 00044 * using the line segments found in digital images. 00045 * 00046 * To achieve this, the lines of an image are extracted 00047 * by a fast line extraction. The edge lines of ellipses are 00048 * filtered by several checks. In further passes these lines 00049 * are combined to arcs, adjacent arcs are combined to extended 00050 * arcs which at last are used to extract ellipses. 00051 * 00052 * The fastEllipseExtraction::parameters specify several 00053 * ranges and conditions that the lines and arcs must fulfill. 00054 * The result strongly depends on these parameters, 00055 * especially the number and the precision of the 00056 * extracted ellipses. 00057 * 00058 * The extracted arcs and ellipses are stored in STL vector 00059 * containers of the types <ellArcEntry>, <ellExtArcEntry> and 00060 * <ellipseEntry>. They can be accessed by the methods 00061 * getEllArcList(), getEllExtArcList and getEllipseList(). 00062 * 00063 * \c ellArcEntry is the data struct for elliptic arcs: 00064 * <pre> struct ellArcEntry 00065 * { 00066 * ipoint start; // start point 00067 * ipoint end; // end point 00068 * ipoint mid; // estimated circle midpoint 00069 * int r2; // estimated squared radius 00070 * ipoint firstVec; // first line vector 00071 * ipoint lastVec; // last line vector 00072 * int used; // counts arc<->extarc assignments 00073 * int group; // base line group (1,2,3 or 4) 00074 * std::vector<int> *lineIdxList; // base line index list 00075 * };</pre> 00076 * 00077 * \c ellExtArcEntry is the data struct for elliptic extended arcs: 00078 * <pre> struct ellExtArcEntry 00079 * { 00080 * double x,y; // estimated ellipse center 00081 * double a,b; // estimated ellipse semi-axis 00082 * double t; // estimated ellipse orientation angle 00083 * double ix, iy; // intersection point of end tangents 00084 * double slopeLB; // slope of line beam 00085 * int used; // counts extarc<->ellipse assignments 00086 * int group; // group of 2nd base arc 00087 * int arcIdx[3];// base arc indices 00088 * };</pre> 00089 * 00090 * \c ellipseEntry is the data struct for ellipses: 00091 * <pre>struct ellipseEntry 00092 * { 00093 * double x,y; // estimated ellipse center 00094 * double a,b; // estimated ellipse semi-axis 00095 * double t; // estimated ellipse orientation angle 00096 * double coverage; // ellipse coverage (accuracy 00097 * std::vector<int> *mergedArcs; // arc index list 00098 * };</pre> 00099 * 00100 * The fast ellipse extraction does not perform any changes 00101 * to the analyzed image. To visualize the extracted ellipses 00102 * they have to be drawn by other code using the 00103 * ellipse lists and a drawing functor. 00104 * 00105 * 00106 * Example: 00107 * \code 00108 * 00109 * #include "ltiViewer.h" // visualization tool 00110 * #include "ltiDraw.h" // drawing tool 00111 * #include "ltiALLfunctor.h" // image loader 00112 * #include "ltiCannyEdges.h" // edge detector 00113 * #include "ltiFastEllipseExtraction.h" // ellipse detector 00114 * 00115 * // ... 00116 * 00117 * lti::image inputImg; 00118 * lti::channel8 edges; 00119 * lti::channel8 result; 00120 * 00121 * // load image 00122 * lti::loadImage loader; 00123 * loader.load("myImage.bmp", inputImg); 00124 * 00125 * // we need the edges 00126 * lti::cannyEdges canny; 00127 * canny.apply(inputImg, edges); 00128 * 00129 * // create FEE functor (using default parameters) 00130 * lti::fastEllipseExtraction fee; 00131 * 00132 * // extract some ellipses 00133 * fee.apply(edges); 00134 * 00135 * // get the ellipse list 00136 * std::vector<lti::fastEllipseExtraction::ellipseEntry> &ellipses = fee.getEllipseList(); 00137 * 00138 * // create a drawing functor 00139 * lti::draw<lti::channel8::value_type> drawer; 00140 * drawer.use(result); 00141 * drawer.setColor(255); 00142 * 00143 * // create background with grey edges 00144 * result = edges; 00145 * result /= 2; 00146 * 00147 * for(int i=0; i<ellipses.size(); i++) { 00148 * // draw ellipse 00149 * lti::point center((int)ellipses[i].x, (int)ellipses[i].y); 00150 * drawer.ellipse(center, (int)ellipses[i].b, (int)ellipses[i].a, ellipses[i].t, false); 00151 * // print ellipse data 00152 * printf("ellipse[%i]: center=(%.0f,%.0f) semiaxis=(%.0f,%.0f) angle=%.1f coverage=%.1f%% \n", 00153 * i, ellipses[i].x, ellipses[i].y, ellipses[i].a, ellipses[i].b, ellipses[i].t*180/3.14, ellipses[i].coverage*100); 00154 * } 00155 * 00156 * // show the extracted ellipses 00157 * lti::viewer view("Detected ellipses"); 00158 * view.show(result); 00159 * 00160 * // wait for a mouse click in the viewer window 00161 * view.waitButtonPressed(); 00162 * 00163 * \endcode 00164 */ 00165 00166 class fastEllipseExtraction : public featureExtractor { 00167 public: 00168 00169 struct segmEntry 00170 { 00171 ipoint start; // start point 00172 ipoint end; // end point 00173 int len; // length 00174 int used; // counts segment<->line assignments 00175 }; 00176 00177 struct lineEntry 00178 { 00179 ipoint start; // start point 00180 ipoint end; // end point 00181 ipoint mid; // midpoint 00182 double tangent; // line tangent 00183 int len; // length 00184 int used; // counts line<->arc assignments 00185 int group; // base segment group (1,2,3 or 4) 00186 std::vector<int> *segmIdxList; // base segment index list 00187 }; 00188 00189 struct ellArcEntry 00190 { 00191 ipoint start; // start point 00192 ipoint end; // end point 00193 ipoint mid; // estimated circle midpoint 00194 int r2; // estimated squared radius 00195 ipoint firstVec; // first line vector 00196 ipoint lastVec; // last line vector 00197 int used; // counts arc<->extarc assignments 00198 int group; // base line group (1,2,3 or 4) 00199 std::vector<int> *lineIdxList; // base line index list 00200 }; 00201 00202 struct ellExtArcEntry 00203 { 00204 double x,y; // estimated ellipse center 00205 double a,b; // estimated ellipse semi-axis 00206 double t; // orientation angle 00207 double ix, iy; // intersection point of end tangents 00208 double slopeLB; // slope of line beam 00209 int used; // counts extarc<->ellipse assignments 00210 int group; // group of 2nd arc 00211 int arcIdx[3];// ell arc indices 00212 }; 00213 00214 struct ellipseEntry 00215 { 00216 double x,y; // estimated ellipse center 00217 double a,b; // estimated ellipse semi-axis 00218 double t; // orientation angle 00219 double coverage; // ellipse coverage (accuracy strongly depends on radius and other effects) 00220 std::vector<int> *mergedArcs; // extarc index list 00221 }; 00222 00223 /** 00224 * the parameters for the class fastEllipseExtraction 00225 */ 00226 class parameters : public featureExtractor::parameters { 00227 public: 00228 /** 00229 * default constructor 00230 */ 00231 parameters(); 00232 00233 /** 00234 * copy constructor 00235 * @param other the parameters object to be copied 00236 */ 00237 parameters(const parameters& other); 00238 00239 /** 00240 * destructor 00241 */ 00242 ~parameters(); 00243 00244 /** 00245 * returns name of this type 00246 */ 00247 const char* getTypeName() const; 00248 00249 /** 00250 * copy the contents of a parameters object 00251 * @param other the parameters object to be copied 00252 * @return a reference to this parameters object 00253 */ 00254 parameters& copy(const parameters& other); 00255 00256 /** 00257 * copy the contents of a parameters object 00258 * @param other the parameters object to be copied 00259 * @return a reference to this parameters object 00260 */ 00261 parameters& operator=(const parameters& other); 00262 00263 00264 /** 00265 * returns a pointer to a clone of the parameters 00266 */ 00267 virtual functor::parameters* clone() const; 00268 00269 /** 00270 * write the parameters in the given ioHandler 00271 * @param handler the ioHandler to be used 00272 * @param complete if true (the default) the enclosing begin/end will 00273 * be also written, otherwise only the data block will be written. 00274 * @return true if write was successful 00275 */ 00276 virtual bool write(ioHandler& handler,const bool complete=true) const; 00277 00278 /** 00279 * read the parameters from the given ioHandler 00280 * @param handler the ioHandler to be used 00281 * @param complete if true (the default) the enclosing begin/end will 00282 * be also written, otherwise only the data block will be written. 00283 * @return true if write was successful 00284 */ 00285 virtual bool read(ioHandler& handler,const bool complete=true); 00286 00287 # ifdef _LTI_MSC_6 00288 /** 00289 * this function is required by MSVC only, as a workaround for a 00290 * very awful bug, which exists since MSVC V.4.0, and still by 00291 * V.6.0 with all bugfixes (so called "service packs") remains 00292 * there... This method is also public due to another bug, so please 00293 * NEVER EVER call this method directly: use read() instead 00294 */ 00295 bool readMS(ioHandler& handler,const bool complete=true); 00296 00297 /** 00298 * this function is required by MSVC only, as a workaround for a 00299 * very awful bug, which exists since MSVC V.4.0, and still by 00300 * V.6.0 with all bugfixes (so called "service packs") remains 00301 * there... This method is also public due to another bug, so please 00302 * NEVER EVER call this method directly: use write() instead 00303 */ 00304 bool writeMS(ioHandler& handler,const bool complete=true) const; 00305 # endif 00306 00307 // ------------------------------------------------ 00308 // the parameters 00309 // ------------------------------------------------ 00310 00311 00312 /** This threshold constant defines the maximum mismatch 00313 * between the found line segments and the estimated analog line. 00314 * The segment is discarded if its starting/finishing pixel 00315 * differs more than <code>maxQuantizationError</code> 00316 * from the estimated analog line. 00317 * If this value is greater than 1.0 the line detection will 00318 * also extract lines that are not completely straight, which 00319 * may be useful for estimation of lines. 00320 * possible values are 00321 * <pre> 00322 * 0.5 < maxQuantizationError 00323 * </pre> 00324 * A high maxQuantizationError value will extract longer lines 00325 * at the cost of precision. Low values result in better pixel 00326 * matching but also in shorter lines. 00327 * Best compromise between pixel matching and good detection 00328 * is a value between 0.6 and 0.7 (the default is 0.79) 00329 */ 00330 float maxQuantizationError; 00331 00332 00333 /** 00334 * This constant defines how much the value of two adjacent pixels 00335 * may differ and still be considered pixels of the same segment. 00336 * A <code>segmentTolerance</code> of 0 will only group pixels 00337 * of the same value to one segment. When analyzing binary maps 00338 * such as edge-images a value of 0 should be used. 00339 * possible values are 00340 * <pre> 00341 * 0 <= segmentTolerance <= 254 00342 * </pre> 00343 * Higher segmentTolerance values allow non-binary 00344 * images to be analysed but may also result in wrong 00345 * segment start/end detection. 00346 * The default is 0 00347 */ 00348 int segmentTolerance; 00349 00350 00351 /** 00352 * The maximum gap two line segments may have and 00353 * still be considered segments of the same line. 00354 * This parameter changes the size of the searching window 00355 * for line segments. Small sizes allow fast processing but may 00356 * also cause detection failures (as well as too high values) 00357 * A <code>maxSegmentGap</code> of 1 will only group 00358 * contiguous segments to a line. 00359 * possible values are 00360 * <pre> 00361 * maxSegmentGap >= 1 (pixel) 00362 * </pre> 00363 * Higher maxSegmentGap values also allow extraction of 00364 * non-contiguous lines such as found in corrupted images. 00365 * The default is 1 00366 */ 00367 int maxSegmentGap; 00368 00369 00370 /** 00371 * The minimum length a line must have to get extracted. 00372 * The parameter <code>minLineLen</code> is used as 00373 * threshold, smaller lines will be ignored. 00374 * possible values are 00375 * <pre> 00376 * minLineLen >= 3 (pixel) 00377 * </pre> 00378 * Values greater than 3 will strongly decrease 00379 * the number of extracted lines and therefore speed up 00380 * the following extraction stages. For most circles 00381 * the optimal value lies between 5 and 7. 00382 * The default is 6 00383 */ 00384 int minLineLen; 00385 00386 00387 /** 00388 * The minimum length a line segment must have to be detected. 00389 * The parameter <code>minSegmLen</code> is used as 00390 * threshold, smaller segments will be ignored. 00391 * Values greater than 2 strongly decrease the number 00392 * of detected segments and the size of the segment lists. 00393 * possible values are 00394 * <pre> 00395 * minSegmLen >= 2 (pixel) 00396 * </pre> 00397 * Values greater than 2 result in smaller segment lists 00398 * and therefore allow slightly faster line detection. 00399 * But mostly good line detection is more important than 00400 * a small speedup, so don't change this parameter unless 00401 * there is a good reason to do so. 00402 * The default is 2 00403 */ 00404 int minSegmLen; 00405 00406 00407 /** 00408 * The maximum gap two lines may have and 00409 * still be considered lines of the same arc. 00410 * This parameter changes the size of the searching window 00411 * for lines. Best results were obtained with small values, 00412 * because large window sizes tend to combine adjacent parallel 00413 * lines to one arc which causes detection failures. 00414 * A <code>maxLineGap</code> of 1 will only group 00415 * contiguous lines to an arc. 00416 * possible values are 00417 * <pre> 00418 * maxLineGap >= 1 (pixel) 00419 * </pre> 00420 * Higher maxLineGap values also allow extraction of 00421 * non-contiguous arcs such as found in corrupted images. 00422 * The default is 3 00423 */ 00424 int maxLineGap; 00425 00426 00427 /** 00428 * The maximum gap two arcs may have and 00429 * still be considered arcs of the same extended arc. 00430 * This parameter changes the size of the searching window 00431 * for arcs. Best results were obtained with large values, 00432 * because every arc has to find at least two neighbours 00433 * to remain in the extraction process. (the gap between 00434 * these arcs mostly lies between 10 and 40 pixels) 00435 * A <code>maxArcGap</code> of 1 will only group 00436 * contiguous arcs to an extended arc. 00437 * possible values are 00438 * <pre> 00439 * maxArcGap >= 1 (pixel) 00440 * </pre> 00441 * Higher maxArcGap values also allow extraction of 00442 * non-contiguous arcs such as found in corrupted images. 00443 * The default is 25 00444 */ 00445 int maxArcGap; 00446 00447 00448 /** This parameter defines the maximum difference that 00449 * the tangents of two lines may have in relation to the 00450 * tangents of the arc that these lines represent. 00451 * In other words, this parameter affects the tolerance 00452 * in terms of roundness of the countour. 00453 * Line pairs which exceed this threshold won't be 00454 * combined to an arc. Too large values result in 00455 * incorrect arcs and detection failures. 00456 * reasonable values are 00457 * <pre> 00458 * 8.5 <= maxLineTangentError <= 20 00459 * </pre> 00460 * Small values cause stricter circle checks 00461 * whereas large values allow more tolerance. 00462 * Best compromise between accuracy and tolerance 00463 * is a value between 10 and 15 (the default is 14) 00464 */ 00465 float maxLineTangentError; 00466 00467 00468 /** This parameter defines the maximum difference that 00469 * the tangents of two arcs may have in relation to the 00470 * tangents of the ellipse that these arcs represent. 00471 * In other words, this parameter affects the tolerance 00472 * in terms of ellipse matching. 00473 * Arcs exceeding this threshold won't be combined 00474 * to an extended arc. Too large values result incorrect 00475 * extended arcs and detection failures. 00476 * reasonable values are 00477 * <pre> 00478 * 10 <= maxArcTangentError <= 20 00479 * </pre> 00480 * Small values cause stricter ellipse checks 00481 * whereas large values allow more tolerance. 00482 * Best results were obtained with more tolerant 00483 * values between 15 and 20 (the default is 18) 00484 */ 00485 float maxArcTangentError; 00486 00487 00488 /** This parameter defines the maximum value that the 00489 * start and end points of one extArc inserted into the 00490 * normal ellipse equation of the other extArc may give. 00491 * ExtArcs which exceed this threshold won't 00492 * be merged into an ellipse. Too large values 00493 * cause detection failures. 00494 * reasonable values are 00495 * <pre> 00496 * 0 < maxExtArcMismatch < 1 00497 * </pre> 00498 * Small values cause stricter ellipse matching checks 00499 * whereas large values allow more tolerance. 00500 * Best compromise between accuracy and tolerance 00501 * is a value between 0.2 and 0.4 (the default is 0.3) 00502 */ 00503 float maxExtArcMismatch; 00504 00505 00506 /** This parameter defines the maximum gap between 00507 * the estimated ellipse centers of two extended arcs. 00508 * ExtArc pairs which exceed this threshold won't be 00509 * combined to an ellipse. Too large values cause 00510 * detection failures. 00511 * reasonable values are 00512 * <pre> 00513 * 1 <= maxCenterMismatch <= 10 00514 * </pre> 00515 * Small values cause stricter extArc matching checks 00516 * whereas large values allow more tolerance. 00517 * Best compromise between accuracy and tolerance 00518 * is a value between 3 and 7 (the default is 5) 00519 */ 00520 float maxCenterMismatch; 00521 00522 00523 /** This parameter defines the minimal matching ratio 00524 * of the estimated ellipse radii of two extended arcs. 00525 * ExtArc pairs which underrun this threshold won't be 00526 * combined to an ellipse. Too small values cause 00527 * detection failures. 00528 * reasonable values are 00529 * <pre> 00530 * 0.5 <= minRadiusMatchRatio <= 0.95 00531 * </pre> 00532 * Large values cause stricter extArc matching checks 00533 * whereas small values allow more tolerance. 00534 * Best compromise between accuracy and tolerance 00535 * is a value between 0.7 and 0.9 (the default is 0.8) 00536 */ 00537 float minRadiusMatchRatio; 00538 00539 00540 /** This parameter defines the minimal coverage for estimated 00541 * ellipses to get extracted. That is the ratio of the estimated 00542 * circumference and the number of extracted arc pixels. 00543 * Ellipses which underrun this threshold won't get extracted. 00544 * Too small values cause extraction of ellipses with randomly 00545 * matching arcs. Also this threshold shouldn't be set to values 00546 * greater than 0.7, since only well fitting parts of a ellipses 00547 * are extracted. Therefore even a completely present ellipse 00548 * may get only 70%% coverage. 00549 * reasonable values are 00550 * <pre> 00551 * 0.2 <= minCoverage <= 0.7 00552 * </pre> 00553 * Best compromise between accuracy and tolerance 00554 * is a value between 0.2 and 0.4 (the default is 0.25) 00555 * Note: Very close and similar ellipses are sometimes 00556 * merged to one ellipse which shows more than 100%% coverage. 00557 */ 00558 float minCoverage; 00559 00560 00561 /** This parameter defines the minimum relative 00562 * distance of two arcs. That is the distance of 00563 * the start points of both arcs compared to the 00564 * start-end point distance of the first arc. 00565 * Arcs which underrun this threshold won't be 00566 * combined to extArcs. 00567 * reasonable values are 00568 * <pre> 00569 * 0 <= minArcDistanceRatio <= 1 00570 * </pre> 00571 * Values <1 allow extraction of overlapping 00572 * arcs. Best results were obtained with values 00573 * between 0.5 and 0.7 (the default is 0.56) 00574 */ 00575 float minArcDistanceRatio; 00576 00577 00578 /** This parameter defines the maximum angle 00579 * between the connection line of the start points 00580 * of two arcs and the line from start point to end 00581 * point of the first arc. 00582 * reasonable values are 00583 * <pre> 00584 * 10 <= maxArcDistanceAngle <= 20 00585 * </pre> 00586 * Small values increase the separation accuracy of 00587 * adjacent ellipse arcs but also lowers tolerance 00588 * against corrupted arcs. Best results were obtained 00589 * with a value of 16 (the default). 00590 */ 00591 float maxArcDistanceAngle; 00592 00593 00594 /** This parameter is a threshold for the gap angle 00595 * check. Arcs with a gap smaller than this value are 00596 * considered close enough to have a continous transition. 00597 * Arcs with greater gaps must pass the additional gap 00598 * angle check. Too large values cause detection failures. 00599 * reasonable values are 00600 * <pre> 00601 * 1 <= minGAPangleDistance <= 3 00602 * </pre> 00603 * Best results were obtained with a value of 2 (the default). 00604 */ 00605 int minGAPangleDistance; 00606 00607 00608 /** This parameter defines the maximum angle between 00609 * the end tangent of the first arc and the start tangent 00610 * of the second arc and the connection tangent. 00611 * Arc pairs which exceed this threshold won't be 00612 * combined to an extArc. Too large values cause 00613 * detection failures whereas too small values reject 00614 * correct arcs. 00615 * reasonable values are 00616 * <pre> 00617 * 25 <= maxGAPangle <= 35 00618 * </pre> 00619 * Best results were obtained with a value of 30 (the default). 00620 */ 00621 float maxGAPangle; 00622 00623 00624 /** This parameter defines the maximum radial gap two 00625 * overlapping arcs. ExtArc pairs which exceed this 00626 * threshold won't be combined to an extArc. 00627 * Too large values cause detection failures. 00628 * reasonable values are 00629 * <pre> 00630 * 1 <= maxArcOverlapGap <= 3 00631 * </pre> 00632 * Best results were obtained with a value of 1 (the default). 00633 */ 00634 float maxArcOverlapGap; 00635 00636 00637 /** This parameter defines the maximum number of errors 00638 * in the interior angle check. The interior angles 00639 * of all lines of the three arcs must be smaller than 90 00640 * degrees to remain in the extArc extraction process. 00641 * Because of image corruptions one or more errors should 00642 * be allowed. Too large values cause detection failures. 00643 * reasonable values are 00644 * <pre> 00645 * 1 <= maxIntAngleMismatches <= 3 00646 * </pre> 00647 * Best results were obtained with a value of 1 (the default). 00648 */ 00649 int maxIntAngleMismatches; 00650 00651 00652 /** This parameter defines the maximum number of errors 00653 * in the arc tangent check. The tangents of all lines of 00654 * the three base arcs of one extArc must match the 00655 * corresponding tangents of the estimated ellipse. 00656 * The maximum difference between ideal and real tangent 00657 * is defined by the parameter maxArcTangentError. 00658 * Because of image corruptions one or more errors should 00659 * be allowed. Too large values cause detection failures. 00660 * reasonable values are 00661 * <pre> 00662 * 1 <= maxTangentErrors <= 3 00663 * </pre> 00664 * Best results were obtained with a value of 1 (the default). 00665 */ 00666 int maxTangentErrors; 00667 00668 00669 /** This parameter defines the maximum distance between 00670 * the line beam of the extArc and the center point of 00671 * the estimated ellipse. 00672 * ExtArcs which exceed this threshold won't be 00673 * combined to an ellipse. Too large values cause 00674 * detection failures. 00675 * reasonable values are 00676 * <pre> 00677 * 1 <= maxLBcenterMismatch <= 10 00678 * </pre> 00679 * Small values cause stricter extArc matching checks 00680 * whereas large values allow more tolerance. 00681 * Best compromise between accuracy and tolerance 00682 * is a value between 3 and 6 (the default is 4) 00683 */ 00684 float maxLBcenterMismatch; 00685 00686 00687 /** The number of checks that an extArc must pass 00688 * before it gets extracted. This parameter was mainly 00689 * used for debugging purposes but might further on be 00690 * useful for the finding of optimal extraction parameters. 00691 * <pre> 00692 * 1 = interior angle check 00693 * 2 = tangent check 00694 * 3 = line beam check 00695 * </pre> 00696 * With a value of 1 or 2 you can examine the behaviour 00697 * of the extArc checks. Unless there is a good reason 00698 * for less extArc checks this this value should be 3. 00699 */ 00700 int ellExtArcExtractionStage; 00701 }; 00702 00703 /** 00704 * default constructor 00705 */ 00706 fastEllipseExtraction(); 00707 00708 /** 00709 * Construct a functor using the given parameters 00710 */ 00711 fastEllipseExtraction(const parameters& par); 00712 00713 /** 00714 * copy constructor 00715 * @param other the object to be copied 00716 */ 00717 fastEllipseExtraction(const fastEllipseExtraction& other); 00718 00719 /** 00720 * destructor 00721 */ 00722 virtual ~fastEllipseExtraction(); 00723 00724 /** 00725 * returns the name of this type ("fastEllipseExtraction") 00726 */ 00727 virtual const char* getTypeName() const; 00728 00729 00730 /** 00731 * Applies fast ellipse detection on-place. 00732 * @param srcdest channel8 with the source data. 00733 * @return true if apply was successful or false otherwise. 00734 */ 00735 bool apply(const channel8& srcdest); 00736 00737 /** 00738 * Applies fast ellipse detection on-place. 00739 * @param srcdest channel with the source data. 00740 * @return true if apply was successful or false otherwise. 00741 */ 00742 bool apply(const channel& srcdest); 00743 00744 /** 00745 * copy data of "other" functor. 00746 * @param other the functor to be copied 00747 * @return a reference to this functor object 00748 */ 00749 fastEllipseExtraction& copy(const fastEllipseExtraction& other); 00750 00751 /** 00752 * alias for copy member 00753 * @param other the functor to be copied 00754 * @return a reference to this functor object 00755 */ 00756 fastEllipseExtraction& operator=(const fastEllipseExtraction& other); 00757 00758 /** 00759 * returns a pointer to a clone of this functor. 00760 */ 00761 virtual functor* clone() const; 00762 00763 /** 00764 * returns used parameters 00765 */ 00766 const parameters& getParameters() const; 00767 00768 00769 /////////////////////////////////////////////////////////// 00770 00771 /** 00772 * returns a vector with line segments of the specified group 00773 * @param groupNumber number of the line segment group (1,2,3,4) 00774 * @return vector with detected line segments 00775 */ 00776 virtual std::vector<segmEntry>& getSegmentList(const int groupNumber); 00777 00778 /** 00779 * returns a vector with lines of the specified group 00780 * @param groupNumber number of the line group (1,2,3,4, or 0 for all lines) 00781 * @return vector with extracted lines 00782 */ 00783 virtual std::vector<lineEntry>& getLineList(const int groupNumber); 00784 00785 /** 00786 * returns a vector with arcs of the specified group 00787 * @param groupNumber number of the arc group (1,2,3,4,5,6,7,8 or 0 for all arcs) 00788 * @return vector with extracted arcs 00789 */ 00790 virtual std::vector<ellArcEntry>& getEllArcList(const int groupNumber); 00791 00792 /** 00793 * returns a vector with extended arcs of the specified group 00794 * @param groupNumber number of the arc group (1,2,3,4,5,6,7,8 or 0 for all arcs) 00795 * @return vector with extracted extended arcs 00796 */ 00797 virtual std::vector<ellExtArcEntry>& getEllExtArcList(const int groupNumber); 00798 00799 /** 00800 * returns a vector with extracted ellipses. 00801 * @return vector with extracted ellipses 00802 */ 00803 virtual std::vector<ellipseEntry>& getEllipseList(); 00804 00805 00806 private: 00807 00808 /** 00809 * clears a line list and its allocated objects 00810 * @param groupNumber number of the line group (0,1,2,3,4) 00811 */ 00812 virtual void clearLineList(const int groupNumber); 00813 00814 /** 00815 * clears an arc list and its allocated objects 00816 * @param groupNumber number of the arc group (0,1,2,3,4,5,6,7,8) 00817 */ 00818 virtual void clearEllArcList(const int groupNumber); 00819 00820 /** 00821 * clears an extended arc list and its allocated objects 00822 * @param groupNumber number of the arc group (0,1,2,3,4,5,6,7,8) 00823 */ 00824 virtual void clearEllExtArcList(const int groupNumber); 00825 00826 /** 00827 * clears the ellipse list and its allocated objects 00828 */ 00829 virtual void clearEllipseList(); 00830 00831 /** 00832 * The segment detection methods. They detect segments by scanning pixel rows. 00833 * For performance and review reasons there are 4 methods (one per segment group). 00834 * Results are stored in STL vectors of type <segmEntry>. These vectors can 00835 * be accessed by the method getSegmentList(). 00836 * @param src channel with source data 00837 */ 00838 virtual void detectGroup1Segments(const channel8& src); 00839 virtual void detectGroup2Segments(const channel8& src); 00840 virtual void detectGroup3Segments(const channel8& src); 00841 virtual void detectGroup4Segments(const channel8& src); 00842 00843 /** 00844 * The line extraction methods. They extract lines by tracking line segments. 00845 * For performance and review reasons there are 4 methods (one per segment group). 00846 * Results are stored in STL vectors of type <lineEntry>. These vectors can 00847 * be accessed by the method getLineList(). 00848 */ 00849 virtual void extractGroup1Lines(); 00850 virtual void extractGroup2Lines(); 00851 virtual void extractGroup3Lines(); 00852 virtual void extractGroup4Lines(); 00853 00854 /** 00855 * The arc extraction methods. They extract arcs by tracking lines. 00856 * For performance and review reasons there are 4 methods (one per segment group). 00857 * Results are stored in STL vectors of type <ellArcEntry>. These vectors can 00858 * be accessed by the method getEllArcList(). 00859 */ 00860 virtual void extractGroup1and5Arcs(); 00861 virtual void extractGroup3and7Arcs(); 00862 virtual void extractGroup2and6Arcs(); 00863 virtual void extractGroup4and8Arcs(); 00864 00865 /** 00866 * The extended arc extraction method. It extracts extended arcs by tracking arcs. 00867 * Results are stored in STL vectors of type <ellExtArcEntry>. These vectors can 00868 * be accessed by the method getEllExtArcList(). 00869 * @param grp the extended arc group to extract 00870 */ 00871 void extractEllExtArcs(const int grp); 00872 00873 00874 /** 00875 * The ellipse extraction method. 00876 * Ellipses are extracted by merging extended arcs. 00877 */ 00878 void extractEllipses(); 00879 00880 00881 /** 00882 * Calculates and checks the interior angles of two arcs. 00883 * @param a index of the first arc 00884 * @param grpA group of the first arc 00885 * @param b index of the second arc 00886 * @param grpB group of the second arc 00887 * @return the number of angle mismatches 00888 */ 00889 int checkInteriorAngles(int a, int grpA, int b, int grpB); 00890 00891 00892 /** 00893 * Calculates and checks the tangent matching of an extended arc and an ellipse. 00894 * @param extarc the arc to be checked 00895 * @param Xest x coordinate of the ellipse 00896 * @param Yest y coordinate of the ellipse 00897 * @param Aest large semi-axis of the ellipse 00898 * @param Best small semi-axis of the ellipse 00899 * @param Test orientation angle of the ellipse 00900 * @return the number of tangent mismatches 00901 */ 00902 int checkEllExtArcTangents(const ellExtArcEntry &extarc, 00903 double Xest, double Yest, double Aest, double Best, double Test); 00904 00905 00906 /** 00907 * Calculates the distance from the linebeam of an extended arc to an ellipse center point. 00908 * The intersection point of the start and end tangents and the line beam slope are stored 00909 * in the given extArc entry. 00910 * @param firstLine first line of the arc to be checked 00911 * @param lastLine last line of the arc to be checked 00912 * @param extarc the arc to be checked 00913 * @param Xest x coordinate of the ellipse 00914 * @param Yest y coordinate of the ellipse 00915 * @return true if successful 00916 */ 00917 bool lineBeamCenterDistance(const lineEntry &firstLine, 00918 const lineEntry &lastLine, 00919 ellExtArcEntry &extarc, 00920 double &distance, const double Xest, const double Yest); 00921 00922 00923 /** 00924 * Calculates the start and end point distance of an extended arc from an estimated ellipse. 00925 * @param extarc the arc to be checked 00926 * @param Xest x coordinate of the ellipse 00927 * @param Yest y coordinate of the ellipse 00928 * @param Aest large semi-axis of the ellipse 00929 * @param Best small semi-axis of the ellipse 00930 * @param Test orientation angle of the ellipse 00931 * @return the maximum distance 00932 */ 00933 double ellipsePointMismatch(ellExtArcEntry &extarc, 00934 double Xest, double Yest, double Aest, double Best, double Test); 00935 00936 00937 /** 00938 * Calculates the intersection point of the line beams of two extended arcs and its 00939 * distance from an ellipse center point. 00940 * @param extarcA first arc 00941 * @param extarcB second arc 00942 * @param Xest x coordinate of the ellipse 00943 * @param Yest y coordinate of the ellipse 00944 * @return the distance of intersection and center point 00945 */ 00946 double lineBeamIsecCenterDistance(const ellExtArcEntry &extarcA, 00947 const ellExtArcEntry &extarcB, 00948 double Xest, double Yest); 00949 00950 00951 /** 00952 * Calculates the distance between a point and a line. 00953 * @param testPtX x coordinate of the point 00954 * @param testPtY y coordinate of the point 00955 * @param linePtY x coordinate of a line point 00956 * @param testPtY y coordinate of a line point 00957 * @param lineSlope slope of the line 00958 * @return the distance between the point and the line. 00959 */ 00960 double linePointDistance(double testPtX, double testPtY, 00961 double linePtX, double linePtY, 00962 double lineSlope); 00963 00964 00965 00966 /** 00967 * Calculates the coverage of an estimated ellipse by approximating the ideal 00968 * circumference and counting the edge pixels of the extracted extended arcs. 00969 * The coverage value is stored in the given ellipse entry. 00970 * @param ellipse the ellipse 00971 */ 00972 void calculateEllipseCoverage(ellipseEntry &ellipse); 00973 00974 00975 00976 /** 00977 * Estimates ellipse parameters by using a least square fitting algorithm. 00978 * @param arcA first arc of the ellipse 00979 * @param arcB second arc of the ellipse 00980 * @param arcC third arc of the ellipse 00981 * @param Xest estimated x coordinate of the ellipse 00982 * @param Yest estimated y coordinate of the ellipse 00983 * @param Aest estimated large semi-axis of the ellipse 00984 * @param Best estimated small semi-axis of the ellipse 00985 * @param Test estimated orientation angle of the ellipse 00986 * @return true if estimation was successful 00987 */ 00988 bool estimateEllipse(const ellArcEntry &arcA, 00989 const ellArcEntry &arcB, 00990 const ellArcEntry &arcC, 00991 double &Xest, double &Yest, double &Aest, double &Best, double &Test); 00992 00993 00994 /** 00995 * Estimates ellipse parameters by using a least square fitting algorithm. 00996 * @param mergedArcs pointer to vector with extArc index numbers 00997 * @param Xest estimated x coordinate of the ellipse 00998 * @param Yest estimated y coordinate of the ellipse 00999 * @param Aest estimated large semi-axis of the ellipse 01000 * @param Best estimated small semi-axis of the ellipse 01001 * @param Test estimated orientation angle of the ellipse 01002 * @return true if estimation was successful 01003 */ 01004 bool estimateEllipse(const std::vector<int> *mergedArcs, 01005 double &Xest, double &Yest, double &Aest, double &Best, double &Test); 01006 01007 01008 /** 01009 * A least square fitting algorithm for ellipse estimation. 01010 * @param Design matrix with ellipse edge pixel data 01011 * @param Xest estimated x coordinate of the ellipse 01012 * @param Yest estimated y coordinate of the ellipse 01013 * @param Aest estimated large semi-axis of the ellipse 01014 * @param Best estimated small semi-axis of the ellipse 01015 * @param Test estimated orientation angle of the ellipse 01016 * @return true if estimation was successful 01017 */ 01018 bool directEllipseFitting(const lti::matrix<double> &Design, 01019 double &Xest, double &Yest, double &Aest, double &Best, double &Test); 01020 01021 01022 /** 01023 * A least square fitting algorithm for ellipse estimation. 01024 * Results are coefficients of the equation for conic sections. 01025 * @param Design matrix with ellipse edge pixel data 01026 * @param A first conic section coefficient 01027 * @param B second conic section coefficient 01028 * @param C third conic section coefficient 01029 * @param D fourth conic section coefficient 01030 * @param E fifth conic section coefficient 01031 * @param F sixth conic section coefficient 01032 * @return true if estimation was successful 01033 */ 01034 bool directEllipseCoefficientFitting(const lti::matrix<double> &Design, 01035 double &A, double &B, double &C, double &D, double &E, double &F); 01036 01037 01038 /** 01039 * Estimates circle parameters by using a least square fitting algorithm. 01040 * @param idxlist vector with arc line index numbers 01041 * @param group group number of the arc lines 01042 * @param Xest the estimated x-coordinate 01043 * @param Yest the estimated y-coordinate 01044 * @param R2est the estimated squared radius 01045 * @return true if calculation was successful 01046 */ 01047 virtual bool estimateCircle(std::vector<int> &idxlist, const int group, 01048 double &Xest, double &Yest, double &R2est); 01049 01050 01051 /** 01052 * The segment containers. (to allow easier implementation 01053 * the arraysize is 5 although only 4 conatainers are used) 01054 * vecSegments[1..4] contain segment groups I..IV, 01055 * vecSegments[0] is not used. 01056 */ 01057 std::vector<segmEntry> vecSegments[5]; 01058 01059 /** 01060 * The line containers. 01061 * vecLines[1..4] contain line groups I..IV, 01062 * vecLines[0] contains all lines. 01063 */ 01064 std::vector<lineEntry> vecLines[5]; 01065 01066 /** 01067 * The elliptic arc containers (8-group classification). 01068 * vecExtArcs[1..9] contain arc groups 1..8, 01069 * vecExtArcs[0] contains all arcs. 01070 */ 01071 std::vector<ellArcEntry> vecEllArcs[9]; 01072 01073 /** 01074 * The elliptic extended arc containers (8-group classification). 01075 * vecEllExtArcs[1..9] contain extArc groups 1..8, 01076 * vecEllExtArcs[0] contains all extended arcs. 01077 */ 01078 std::vector<ellExtArcEntry> vecEllExtArcs[9]; 01079 01080 /** 01081 * The ellipse container. 01082 */ 01083 std::vector<ellipseEntry> vecEllipses; 01084 01085 /** 01086 * The input image width. Needed for coordinate transformation 01087 * when extracting diagonal lines. 01088 */ 01089 int imageWidth; 01090 01091 /** 01092 * The number of pre-allocated vector entries. 01093 */ 01094 static const int segmPreallocation; 01095 static const int linePreallocation; 01096 static const int ellArcPreallocation; 01097 static const int ellExtArcPreallocation; 01098 static const int ellipsePreallocation; 01099 01100 /** 01101 * Numeric constants. 01102 */ 01103 static const double PI; 01104 static const double INFINITE_SLOPE; 01105 01106 }; 01107 } 01108 01109 #endif