1 /**************************************************************************** 2 * 3 * ViSP, open source Visual Servoing Platform software. 4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved. 5 * 6 * This software is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * See the file LICENSE.txt at the root directory of this source 11 * distribution for additional information about the GNU GPL. 12 * 13 * For using ViSP with software that can not be combined with the GNU 14 * GPL, please contact Inria about acquiring a ViSP Professional 15 * Edition License. 16 * 17 * See http://visp.inria.fr for more information. 18 * 19 * This software was developed at: 20 * Inria Rennes - Bretagne Atlantique 21 * Campus Universitaire de Beaulieu 22 * 35042 Rennes Cedex 23 * France 24 * 25 * If you have questions regarding the use of this file, please contact 26 * Inria at visp@inria.fr 27 * 28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 30 * 31 * Description: 32 * Moving edges. 33 * 34 * Authors: 35 * Eric Marchand 36 * 37 *****************************************************************************/ 38 39 /*! 40 \file vpMeLine.h 41 \brief Moving edges on a line 42 */ 43 44 #ifndef vpMeLine_HH 45 #define vpMeLine_HH 46 47 #include <visp3/core/vpMath.h> 48 #include <visp3/core/vpMatrix.h> 49 #include <visp3/me/vpMeTracker.h> 50 51 #include <iostream> 52 #include <math.h> 53 54 /*! 55 \class vpMeLine 56 57 \ingroup module_me 58 59 \brief Class that tracks in an image a line moving edges. 60 61 In this class the line is defined by its equation in the \f$ (i,j) = 62 (line,column) \f$ image plane. Two kinds of parametrization are available to 63 describe a 2D line. The first one corresponds to the following 64 equation 65 66 \f[ ai + bj + c = 0 \f] 67 68 where \f$ i \f$ and \f$ j \f$ are the coordinates of the points 69 belonging to the line. The line features are \f$ (a, b, c) \f$. 70 71 The second way to write the line equation is to consider polar coordinates 72 \f[ i \; cos(\theta) + j \; sin(\theta) - \rho = 0 \f] 73 74 where \f$ i \f$ and \f$ j \f$ are still the coordinates of the 75 points belonging to the line. But now the line features are \f$ 76 (\rho, \theta) \f$. The computation of \f$ \rho \f$ and \f$ \theta 77 \f$ is easy thanks to \f$ (a, b, c) \f$. 78 79 \f[ \theta = arctan(b/a) \f] 80 \f[ \rho = -c/\sqrt{a^2+b^2} \f] 81 82 The value of \f$ \theta \f$ is between \f$ 0 \f$ and \f$ 2\pi 83 \f$. And the value of \f$ \rho \f$ can be positive or negative. The 84 conventions to find the right values of the two features are 85 illustrated in the following pictures. 86 87 \image html vpMeLine.gif 88 \image latex vpMeLine.ps width=10cm 89 90 The angle \f$\theta\f$ is computed thanks to the direction of the 91 arrow. The arrow points to the side of the line which is darker. 92 93 The example below available in tutorial-me-line-tracker.cpp and described 94 in \ref tutorial-tracking-me shows how to use this class. 95 96 \include tutorial-me-line-tracker.cpp 97 98 The code below shows how to use this class. 99 \code 100 #include <visp3/core/vpConfig.h> 101 #include <visp3/core/vpImage.h> 102 #include <visp3/core/vpImagePoint.h> 103 #include <visp3/me/vpMeLine.h> 104 105 int main() 106 { 107 vpImage<unsigned char> I(240, 320); 108 109 // Fill the image with a black rectangle 110 I = 0; 111 for (int i = 100; i < 180; i ++) { 112 for (int j = 120; j < 250; j ++) { 113 I[i][j] = 255; 114 } 115 } 116 117 // Set the moving-edges tracker parameters 118 vpMe me; 119 me.setRange(25); 120 me.setThreshold(15000); 121 me.setSampleStep(10); 122 123 // Initialize the moving-edges line tracker parameters 124 vpMeLine line; 125 line.setMe(&me); 126 127 // Initialize the location of the vertical line to track 128 vpImagePoint ip1, ip2; // Two points belonging to the line to track 129 ip1.set_i( 120 ); 130 ip1.set_j( 119 ); 131 ip2.set_i( 170 ); 132 ip2.set_j( 122 ); 133 134 line.initTracking(I, ip1, ip2); 135 136 while ( 1 ) 137 { 138 // ... Here the code to read or grab the next image. 139 140 // Track the line. 141 line.track(I); 142 } 143 return 0; 144 } 145 \endcode 146 147 \note It is possible to display the line as an overlay. For that you 148 must use the display function of the class vpMeLine. 149 */ 150 151 class VISP_EXPORT vpMeLine : public vpMeTracker 152 { 153 private: 154 static void update_indices(double theta, int incr, int i, int j, int &i1, int &i2, int &j1, int &j2); 155 156 protected: 157 vpMeSite PExt[2]; 158 159 double rho, theta; 160 double delta, delta_1; 161 double angle, angle_1; 162 int sign; 163 164 //! Flag to specify wether the intensity of the image at the middle point is 165 //! used to compute the sign of rho or not. 166 bool _useIntensityForRho; 167 168 #ifdef VISP_BUILD_DEPRECATED_FUNCTIONS 169 public: 170 #else 171 protected: 172 #endif 173 174 double a; //!< Parameter a of the line equation a*i + b*j + c = 0 175 double b; //!< Parameter b of the line equation a*i + b*j + c = 0 176 double c; //!< Parameter c of the line equation a*i + b*j + c = 0 177 178 public: 179 vpMeLine(); 180 vpMeLine(const vpMeLine &meline); 181 virtual ~vpMeLine(); 182 183 void display(const vpImage<unsigned char> &I, vpColor col); 184 185 void track(const vpImage<unsigned char> &Im); 186 187 virtual void sample(const vpImage<unsigned char> &image, bool doNotTrack=false); 188 void reSample(const vpImage<unsigned char> &I); 189 void leastSquare(); 190 void updateDelta(); 191 void setExtremities(); 192 void seekExtremities(const vpImage<unsigned char> &I); 193 void suppressPoints(); 194 195 void initTracking(const vpImage<unsigned char> &I); 196 void initTracking(const vpImage<unsigned char> &I, const vpImagePoint &ip1, const vpImagePoint &ip2); 197 198 void computeRhoTheta(const vpImage<unsigned char> &I); 199 double getRho() const; 200 double getTheta() const; 201 void getExtremities(vpImagePoint &ip1, vpImagePoint &ip2); 202 203 /*! 204 Gets the equation parameters of the line 205 */ getEquationParam(double & A,double & B,double & C)206 void getEquationParam(double &A, double &B, double &C) 207 { 208 A = a; 209 B = b; 210 C = c; 211 } 212 213 /*! 214 Gets parameter a of the line equation a*i + b*j + c = 0 215 */ getA()216 inline double getA() const { return a; } 217 218 /*! 219 Gets parameter b of the line equation a*i + b*j + c = 0 220 */ getB()221 inline double getB() const { return b; } 222 223 /*! 224 Gets parameter c of the line equation a*i + b*j + c = 0 225 */ getC()226 inline double getC() const { return c; } 227 228 static bool intersection(const vpMeLine &line1, const vpMeLine &line2, vpImagePoint &ip); 229 230 /*! 231 This method allows to turn off the computation of the sign of the rho 232 attribute based on the intensity near the middle point of the line. This 233 is usually done to distinguish between a black/white and a white/black 234 edge but it may be source of problem (ex. for a servoing example) when 235 this point can be occluded. 236 237 \param useIntensityForRho : new value of the flag. 238 */ computeRhoSignFromIntensity(bool useIntensityForRho)239 inline void computeRhoSignFromIntensity(bool useIntensityForRho) { _useIntensityForRho = useIntensityForRho; } 240 241 // Static Functions 242 public: 243 static void display(const vpImage<unsigned char> &I, const vpMeSite &PExt1, const vpMeSite &PExt2, const double &A, 244 const double &B, const double &C, const vpColor &color = vpColor::green, 245 unsigned int thickness = 1); 246 static void display(const vpImage<vpRGBa> &I, const vpMeSite &PExt1, const vpMeSite &PExt2, const double &A, 247 const double &B, const double &C, const vpColor &color = vpColor::green, 248 unsigned int thickness = 1); 249 250 static void display(const vpImage<unsigned char> &I, const vpMeSite &PExt1, const vpMeSite &PExt2, 251 const std::list<vpMeSite> &site_list, const double &A, const double &B, const double &C, 252 const vpColor &color = vpColor::green, unsigned int thickness = 1); 253 static void display(const vpImage<vpRGBa> &I, const vpMeSite &PExt1, const vpMeSite &PExt2, 254 const std::list<vpMeSite> &site_list, const double &A, const double &B, const double &C, 255 const vpColor &color = vpColor::green, unsigned int thickness = 1); 256 }; 257 258 #endif 259