DIMANCHE 16 SEPTEMBRE 2012 Régression circulaire
Ce billet est consacré à la régression d'un ensemble de points (x; y) par un cercle défini par son centre (a; b) et son rayon R. Il s'agit plus d'un mémo pour moi-même qu'autre chose. J'en profite pour tester également les iframe sur TinyMCE ainsi que les formules mathématiques en MathML, rédigées sous LibreOffice. Le document html en question est disponible à l'adresse suivante :
http://floriansella.free.fr/images/blogs/RegressionCirculaire/RegressionCirculaire.html
Revenons à notre régression circulaire. N'étant pas mathématicien, mon document manque probablement de rigueur. Cependant, il est amplement suffisant pour des gens comme moi, c'est-à-dire des ingénieurs en traitement d'images.
A noter que vous trouverez quelque chose de plus sérieux à l'adresse suivante :
www.scribd.com/doc/14819165/Regressions-coniques-quadriques-circulaire-spherique
Dans ce document, l'étude se sert notamment d'un changement de variables que j'ai supprimé par simplicité.
Voilà un petit exemple pour mettre en application tout ça. Il s'agit de calculer un ensemble de points autour d'un cercle défini par son centre (20.5; -3.7) et son rayon 8. Les coordonnées de chaque point sont bruitées par le code suivant :
double const xnoise = 2.0 * (double)(rand() % 200 - 100) / 100.0; double const ynoise = 2.0 * (double)(rand() % 200 - 100) / 100.0; |
Voici la sortie des résultats :
--------------------------------------------------------------------- ||Expected circle : || x center = 20.5 || y center = -3.7 || radius = 8 --------------------------------------------------------------------- ||x original| x noised| noise ||y original| y noised| noise|| --------------------------------------------------------------------- || 28.5| 27.32| -1.18 || -3.7| -4.36| -0.66|| || 28.3252| 29.0052| 0.68 || -2.03675| -2.03675| 0|| || 27.8084| 29.1884| 1.38 || -0.446197| 0.0338029| 0.48|| || 26.9722| 26.5322| -0.44 || 1.00216| 2.16216| 1.16|| || 25.8532| 27.0932| 1.24 || 2.24503| 1.52503| -0.72|| || 24.5002| 24.6002| 0.1 || 3.22808| 4.12808| 0.9|| || 22.9724| 22.5924| -0.38 || 3.90836| 2.44836| -1.46|| || 21.3366| 22.5566| 1.22 || 4.25614| 4.07614| -0.18|| || 19.6642| 21.5642| 1.9 || 4.25622| 5.09622| 0.84|| || 18.0283| 16.5683| -1.46 || 3.90859| 2.62859| -1.28|| || 16.5004| 18.3204| 1.82 || 3.22845| 1.30845| -1.92|| || 15.1474| 15.1874| 0.04 || 2.24552| 3.30552| 1.06|| || 14.0282| 13.8682| -0.16 || 1.00276| 2.64276| 1.64|| || 13.1919| 11.6119| -1.58 || -0.44552| -0.12552| 0.32|| || 12.675| 13.035| 0.36 || -2.03603| -2.13603| -0.1|| || 12.5| 11.44| -1.06 || -3.69926| -3.17926| 0.52|| || 12.6747| 14.0947| 1.42 || -5.36252| -4.60252| 0.76|| || 13.1913| 12.5713| -0.62 || -6.95313| -6.71313| 0.24|| || 14.0273| 13.3673| -0.66 || -8.40156| -8.42156| -0.02|| || 15.1463| 13.8463| -1.3 || -9.64453| -9.76453| -0.12|| || 16.4991| 16.5591| 0.06 || -10.6277| -12.4077| -1.78|| || 18.0269| 18.4669| 0.44 || -11.3081| -10.6481| 0.66|| || 19.6627| 19.1227| -0.54 || -11.6561| -12.3761| -0.72|| || 21.3351| 22.1551| 0.82 || -11.6563| -11.4363| 0.22|| || 22.971| 22.031| -0.94 || -11.3088| -11.9488| -0.64|| || 24.4989| 25.4389| 0.94 || -10.6288| -11.7488| -1.12|| || 25.8521| 25.0921| -0.76 || -9.64602| -8.50602| 1.14|| || 26.9714| 25.7114| -1.26 || -8.40336| -9.22336| -0.82|| || 27.8078| 28.2678| 0.46 || -6.95516| -6.13516| 0.82|| || 28.3249| 28.9049| 0.58 || -5.3647| -3.8047| 1.56|| --------------------------------------------------------------------- ||Computed circle : || x center = 20.3688 || y center = -3.76401 || radius = 8.25942 || rmse = 1.01834 ---------------------------------------------------------------------
|
Le cercle prédit est localisé en (20.36; -3.76) avec un rayon de 8.25 et un rmse (Root Mean Square Error) de 1.01834.
Le code est disponible à l'adresse suivante :
http://floriansella.free.fr/images/blogs/RegressionCirculaire/CircularRegression.zip
Aucune dépendance (boost, opencv, ou je sais pas quoi d'autre ... ) n'est requise juste un "g++ main.cpp matrix.cpp -o test" pour compiler. Vous pouvez utiliser ce code sans restriction aucune. Son utilisation est très simple :
// variables
std::vector<double> xlist; // ... The list of the x coordinates of the points that match a circle.
std::vector<double> ylist; // ... The list of the y coordinates of the points that match a circle.
double xcenter = 0.0; // To store the x coordinate of the center of the circle computed by the function.
double ycenter = 0.0; // To store the y coordinate of the center of the circle computed by the function.
double radius = 0.0; // To store the radius of the circle computed by the function.
double rmse = 0.0; // To store the root mean square error resulted from the regression.
try
{
// regression of the points by a circle
Matrix::circularRegression(xlist, ylist, xcenter, ycenter, radius, rmse);
}
catch(std::exception const & error)
{
std::cout << error.what() << std::endl;
}
catch(...)
{
std::cout << "An undefined error has occured" << std::endl;
}
|
Un petit merci si ça vous a servi à quelque chose. Sinon pas grave.
A noter que ceci a fait l'objet d'une contribution de ma part sous developpez.com. Je dis pas ça pour me la péter mais le fil des messages associé à cette contribution aura tôt fait d'être plus étoffé que ce pauvre blog vide de visiteurs. La contribution en question est disponible à l'adresse suivante :
http://www.developpez.net/forums/d1262000/autres-langages/algorithmes/contribuez/cpp-regression-circulaire/
PS pour les mathématiciens : pas taper !
(Dernière édition 2012-09-17 à 21:18:51)
double const xnoise = 2.0 * (double)(rand() % 200 - 100) / 100.0;
double const ynoise = 2.0 * (double)(rand() % 200 - 100) / 100.0;
PUBLIE PAR FLORIAN A 17:39:05 Enregistré dans la ou les catégories maths
|