latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2002, 2003, 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 .......: ltiOrientedHLTransform.h 00027 * authors ....: Henning Luepschen 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 02.10.2002 00030 * revisions ..: $Id: ltiOrientedHLTransform.h,v 1.10 2006/02/08 11:36:36 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_ORIENTED_HL_TRANSFORM_H_ 00034 #define _LTI_ORIENTED_HL_TRANSFORM_H_ 00035 00036 #include "ltiTransform.h" 00037 00038 namespace lti { 00039 00040 /** 00041 * This functor is used to make a fast Hough Line Transform 00042 * and creates a channel32 transformation accumulator. 00043 * 00044 * The houghLineTransform::parameters specify what part of 00045 * a given image/channel is transformed and which point values 00046 * are considered. 00047 * 00048 * To accelerate the computations, an orientation map containing the angles 00049 * perpendicular to the edges is used. This can be generated using 00050 * for example lti::orientationMap. 00051 * 00052 * Two additional methods help in the use of the hough space. The first 00053 * one detects the local maxima ( getHoughSpacePoints() ), and the second 00054 * one finds two points that define the line segment found in the image 00055 * ( getSegmentPoints() ). 00056 * 00057 * The hough space contains as expected two parameters: radius and angle. 00058 * They are measured from the middle point of the analysed region. The angle 00059 * is always between 0 and 180 degrees. The radius can be negative and its 00060 * absolute value will be between 0 and the image diagonal divided by two. 00061 * 00062 * Example: 00063 * \code 00064 * 00065 * #include "ltiOrientedHLTransform.h" // the hough transform 00066 * #include "ltiCannyEdges.h" // the edge detector 00067 * #include "ltiALLFunctor.h" // to read png, jpg and bmp images 00068 * #include "ltiDraw.h" // drawing tool 00069 * #include "ltiViewer.h" // visualization tool 00070 * 00071 * // ... 00072 * 00073 * lti::image inputImg; 00074 * lti::channel8 edges; 00075 * lti::channel angles; // orientation map 00076 * lti::channel32 transformAccu; 00077 * 00078 * // load an image and extract the intensity channel from it 00079 * lti::loadImage imgLoader; 00080 * imgLoader.load("../img/hough1.png",inputImg); // load an image 00081 * 00082 * // we need the edges 00083 * cannyEdges canny; 00084 * canny.apply(inputImg,edges,angles); 00085 * 00086 * // create default HLT (Hough Line Transform) using default parameters 00087 * lti::orientedHLTransform HLT; 00088 * 00089 * // The Hough Transform 00090 * HLT.apply(edges,angles,transformAccu); 00091 * 00092 * // Display the Hough space 00093 * viewer viewHS("Hough Space"); 00094 * viewHS.show(transformAccu); 00095 * 00096 * // Now get the local maxima of the transformAccu 00097 * lti::vector< tpoint<float> > maxpos; 00098 * HLT.getHoughSpacePoints(transformAccu,maxpos); 00099 * 00100 * // And draw the found lines in the original image 00101 * lti::draw<rgbPixel> drawer; 00102 * drawer.use(inputImg); 00103 * drawer.setColor(lti::White); 00104 * point a,b; 00105 * for (int k=0;k<maxpos.size();++k) { 00106 * HLT.getSegmentPoints(inputImg.size(),maxpos.at(k).x,maxpos.at(k).y,a,b); 00107 * drawer.line(a,b); 00108 * } 00109 * 00110 * // at last, show the resulting lines 00111 * viewer view("Detected lines"); 00112 * view.show(inputImg); 00113 * 00114 * view.waitButtonPressed(); // wait until the user presses the mouse button 00115 * // on the viewer window. 00116 * \endcode 00117 */ 00118 class orientedHLTransform : public transform { 00119 public: 00120 /** 00121 * the parameters for the class orientedHLTransform 00122 */ 00123 class parameters : public transform::parameters { 00124 public: 00125 /** 00126 * default constructor 00127 */ 00128 parameters(); 00129 00130 /** 00131 * copy constructor 00132 * @param other the parameters object to be copied 00133 */ 00134 parameters(const parameters& other); 00135 00136 /** 00137 * destructor 00138 */ 00139 ~parameters(); 00140 00141 /** 00142 * returns name of this type 00143 */ 00144 const char* getTypeName() const; 00145 00146 /** 00147 * copy the contents of a parameters object 00148 * @param other the parameters object to be copied 00149 * @return a reference to this parameters object 00150 */ 00151 parameters& copy(const parameters& other); 00152 00153 /** 00154 * copy the contents of a parameters object 00155 * @param other the parameters object to be copied 00156 * @return a reference to this parameters object 00157 */ 00158 parameters& operator=(const parameters& other); 00159 00160 00161 /** 00162 * returns a pointer to a clone of the parameters 00163 */ 00164 virtual functor::parameters* clone() const; 00165 00166 /** 00167 * write the parameters in the given ioHandler 00168 * @param handler the ioHandler to be used 00169 * @param complete if true (the default) the enclosing begin/end will 00170 * be also written, otherwise only the data block will be written. 00171 * @return true if write was successful 00172 */ 00173 virtual bool write(ioHandler& handler,const bool complete=true) const; 00174 00175 /** 00176 * read the parameters from the given ioHandler 00177 * @param handler the ioHandler to be used 00178 * @param complete if true (the default) the enclosing begin/end will 00179 * be also written, otherwise only the data block will be written. 00180 * @return true if write was successful 00181 */ 00182 virtual bool read(ioHandler& handler,const bool complete=true); 00183 00184 # ifdef _LTI_MSC_6 00185 /** 00186 * this function is required by MSVC only, as a workaround for a 00187 * very awful bug, which exists since MSVC V.4.0, and still by 00188 * V.6.0 with all bugfixes (so called "service packs") remains 00189 * there... This method is also public due to another bug, so please 00190 * NEVER EVER call this method directly: use read() instead 00191 */ 00192 bool readMS(ioHandler& handler,const bool complete=true); 00193 00194 /** 00195 * this function is required by MSVC only, as a workaround for a 00196 * very awful bug, which exists since MSVC V.4.0, and still by 00197 * V.6.0 with all bugfixes (so called "service packs") remains 00198 * there... This method is also public due to another bug, so please 00199 * NEVER EVER call this method directly: use write() instead 00200 */ 00201 bool writeMS(ioHandler& handler,const bool complete=true) const; 00202 # endif 00203 00204 // ------------------------------------------------ 00205 // the parameters 00206 // ------------------------------------------------ 00207 00208 /** 00209 * Part of the input image/channel that will be considered for 00210 * transformation. 00211 * 00212 * If this area is bigger than the image/channel size given in the 00213 * apply() method, the size of the channel will be used. 00214 * 00215 * The default values are (0,0, 00216 * std::numeric_limits<int>::max(), 00217 * std::numeric_limits<int>::max()) 00218 * (i.e. use the whole image) 00219 */ 00220 trectangle<int> transformationArea; 00221 00222 /** 00223 * All points of the input image/channel whose value is greater 00224 * than the base value are used for transformation. 00225 * (usually the base value will be 0 (or a little higher) which 00226 * results in all coloured lines being considered on a black background) 00227 * 00228 * For channels (with float values), the comparison value will be 00229 * baseValue/255.0. 00230 * 00231 * Default Value: 0 00232 */ 00233 int baseValue; 00234 00235 /** 00236 * Accuracy of Hough Line Transformation. Determines what kind of 00237 * line angles can be detected. The following values are 00238 * allowed: 00239 * - 45 (4 degrees steps) : very inaccurate, but very fast 00240 * - 90 (2 degrees steps) : inaccurate, but fast 00241 * - 180 (1 degree steps) : quite accurate 00242 * - 360 (1/2 degree steps) : accurate, but slower 00243 * - 540 (1/3 degree steps) : very accurate, but very slow 00244 * - 720 (1/4 degree steps) : even more accurate, but even slower... 00245 * - ... 00246 * 00247 * Higher values that are divisible by 180 are also allowed, but 00248 * do make the transformation _really_ slow. 00249 * 00250 * Default value: 180 00251 */ 00252 int accuracy; 00253 00254 /** 00255 * Angle range. The sinusoids are only be drawn from 00256 * (gradientAngle-range) to (gradientAngle+range). Values lower 00257 * than 5 are not recommended. 00258 * 00259 * Default value is 10. 00260 */ 00261 int range; 00262 00263 /** 00264 * Accumulation modes 00265 */ 00266 enum eAccumulationMode { 00267 Classic, /**< A value of 1 will be accumulated in the hough space 00268 * each time an edge is found with a value greater than 00269 * baseValue 00270 */ 00271 Gradient /**< The value in the given edges image will be accumulated 00272 * allowing to weight the strongness of an edge. If the 00273 * edges image is a channel, their values will be 00274 * multiplied by 255 before accumulating. 00275 */ 00276 }; 00277 00278 /** 00279 * mode used for the accumulation 00280 * 00281 * Default: Classic 00282 */ 00283 eAccumulationMode accumulationMode; 00284 }; 00285 00286 /** 00287 * default constructor, member variable m_iAccuracy is set to 180 00288 * @see m_iAccuracy() 00289 * @see setAccuracy() 00290 * @see getAccuracy() 00291 */ 00292 orientedHLTransform(); 00293 00294 /** 00295 * copy constructor 00296 * @param other the object to be copied 00297 */ 00298 orientedHLTransform(const orientedHLTransform& other); 00299 00300 /** 00301 * destructor 00302 */ 00303 virtual ~orientedHLTransform(); 00304 00305 /** 00306 * returns the name of this type ("orientedHLTransform") 00307 */ 00308 virtual const char* getTypeName() const; 00309 00310 /** 00311 * operates on a copy of the given %parameters. 00312 * @param src channel with the source data (gradient). 00313 * @param angle_src channel with gradient angles. 00314 * @param dest channel32 where the result will be left. 00315 * @return true if apply successful or false otherwise. 00316 */ 00317 bool apply(const channel& src, 00318 const channel& angle_src, 00319 channel32& dest) const; 00320 00321 /** 00322 * operates on a copy of the given %parameters. 00323 * @param src channel8 with the source data. 00324 * @param angle_src channel with gradient angles. 00325 * @param dest channel32 where the result will be left. 00326 * @return true if apply successful or false otherwise. 00327 */ 00328 bool apply(const channel8& src, 00329 const channel& angle_src, 00330 channel32& dest) const; 00331 00332 /** 00333 * Make Hough Transform of the given image and 00334 * write the transformation accumulator into dest. 00335 * 00336 * operates on a copy of the given %parameters. 00337 * @param src image with the source data. 00338 * @param angle_src channel with gradient angles. 00339 * @param dest channel32 where the result will be left. 00340 * @return true if apply successful or false otherwise. 00341 */ 00342 bool apply(const image& src, 00343 const channel& angle_src, 00344 channel32& dest) const; 00345 00346 /** 00347 * operates on a copy of the given %parameters. 00348 * @param src channel32 with the source data. 00349 * @param angle_src channel with gradient angles. 00350 * @param dest channel32 where the result will be left. 00351 * @return true if apply successful or false otherwise. 00352 */ 00353 bool apply(const channel32& src, 00354 const channel& angle_src, 00355 channel32& dest) const; 00356 00357 00358 /** 00359 * @name Help methods 00360 */ 00361 //@{ 00362 00363 /** 00364 * This method is used to get the list of points in the parameter 00365 * space, sorted by their hough transformation value, with the 00366 * maxima at the beginning. 00367 * 00368 * @param hough a hough transformation image, as produced by the apply 00369 * methods 00370 * @param positions the positions of the points found in the hough image, 00371 * sorted by the hough value. The x value will be the 00372 * radius (in pixels) and the y value the angle 00373 * (in radians). 00374 * @param stdDevFactor the average and std. deviation values 00375 * between all detected maxima will be computed. 00376 * Only those values greater than the average plus this 00377 * parameter multiplied by the std. deviation will be 00378 * considered. Default value 1.0 should be ok. 00379 * @param hystheresis to detect the local maxima a region search starting 00380 * from preliminary maxima will be done. This value 00381 * multiplied by the preliminary maxima determine the 00382 * threshold that must be reached in order to continue 00383 * the search. The value must be between 0 and 1. If 00384 * it is choose too low, just the biggest maxima will 00385 * be found. If too high, too many maxima will be 00386 * found. Default value 0.5 work well for the most 00387 * cases. 00388 */ 00389 bool getHoughSpacePoints(const channel32& hough, 00390 vector< tpoint<float> >& positions, 00391 const float stdDevFactor = 1.0f, 00392 const float hystheresis = 0.5f) const; 00393 00394 00395 /** 00396 * Given a radius and an angle, compute the two points at the border of 00397 * the image. 00398 * @param imageSize size of the image for which the points a and b 00399 * need to be computed 00400 * @param radius radius parameter of the hough space 00401 * @param angle angle parameter of the hough space 00402 * @param a begin point 00403 * @param b end point 00404 * @param origin optional parameter that specifies the origin of 00405 * the coordinates system in the image. If not given 00406 * or if it contains negative values, the middle of the 00407 * image will be used as origin. 00408 */ 00409 bool getSegmentPoints(const point& imageSize, 00410 const float radius, 00411 const float angle, 00412 point& a, 00413 point& b, 00414 const point& origin = point(-1,-1)) const; 00415 00416 //@} 00417 00418 00419 /** 00420 * copy data of "other" functor. 00421 * @param other the functor to be copied 00422 * @return a reference to this functor object 00423 */ 00424 orientedHLTransform& copy(const orientedHLTransform& other); 00425 00426 /** 00427 * alias for copy member 00428 * @param other the functor to be copied 00429 * @return a reference to this functor object 00430 */ 00431 orientedHLTransform& operator=(const orientedHLTransform& other); 00432 00433 /** 00434 * returns a pointer to a clone of this functor. 00435 */ 00436 virtual functor* clone() const; 00437 00438 /** 00439 * returns used parameters 00440 */ 00441 const parameters& getParameters() const; 00442 00443 /** 00444 * set functor's parameters. 00445 * This member makes a copy of <em>theParam</em>: the functor 00446 * will keep its own copy of the parameters! 00447 * @return true if successful, false otherwise 00448 */ 00449 virtual bool updateParameters(); 00450 00451 /** 00452 * returns accuracy of Hough Line Transform 00453 * @see m_iAccuracy() 00454 * @return value of member variable m_iAccuracy 00455 */ 00456 int getAccuracy() const; 00457 00458 /** 00459 * sets accuracy of Hough Line Transform and creates the 00460 * appropriate sinus and cosinus integer tables 00461 * @see m_iAccuracy() 00462 * @return true, if successful 00463 */ 00464 bool setAccuracy( int iAccuracy ); 00465 00466 private: 00467 /** 00468 * Create sinus/cosinus integer tables of given size. 00469 */ 00470 void createSinCosTable(const int iSize); 00471 00472 /** 00473 * Pointer to cosinus integer table. We want to speed 00474 * the transformation up. 00475 */ 00476 int* m_pCosinus; 00477 00478 /** 00479 * Pointer to sinus integer table. We want to speed 00480 * the transformation up. 00481 */ 00482 int* m_pSinus; 00483 00484 /** 00485 * Accuracy of Hough Line Transform. Determines what kind of 00486 * line angles can be detected. The following values are 00487 * allowed: 00488 * 00489 * 45 (4 degrees steps) : very inaccurate, but very fast 00490 * 90 (2 degrees steps) : inaccurate, but fast 00491 * 180 (1 degree steps) : quite accurate 00492 * 360 (1/2 degree steps) : accurate, but slower 00493 * 540 (1/3 degree steps) : very accurate, but very slow 00494 * 720 (1/4 degree steps) : even more accurate, but even slower... 00495 * ... 00496 * 00497 * Higher values that are divisible by 180 are also allowed, but 00498 * do make the transformation _really_ slow. 180 is the DEFAULT value. 00499 * 00500 * ------------------------------------------------------------------- 00501 * The private copy of the parameters.accuracy is only kept in order 00502 * to check if it is necessary to create _new_ sinus/cosinus tables 00503 * ------------------------------------------------------------------- 00504 */ 00505 int m_iAccuracy; 00506 }; 00507 00508 } 00509 00510 #endif