Ben314 a écrit:Quelques remarques :
- Je pense qu'il faut non seulement pas mal de points, mais je pense que pour que ça marche bien il faut un nombre à peu prés équivalent de points sur les deux branches de la parabole et qu'ils soient à peu prés répartis de la même façon par rapport au centre de la parabole (si d'un coté ils sont relativement proche du centre et pas de l'autre ça va déconner) vu que l'axe de la parabole, on le cherche en cherchant la droite qui maximise la somme des carrés des distances à la droite. Je sais pas si ça déconnerais pas aussi si la parabole est très aplati (ou il risque de trouver l'axe des Y comme droite maximisante).
Ben314 a écrit:sous forme paramétrique comme semble le suggérer ton précédent message.
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
int main()
{
// Création d'une matrice carrée
cv::Mat mat = cv::Mat::zeros(3, 3, CV_32FC1); // Exemple : matrice nulle
try
{
// Calcul de l'inverse de la matrice
cv::Mat inverse;
cv::invert(mat, inverse);
// Affichage de l'inverse de la matrice
std::cout << "Inverse de la matrice :\n" << inverse << std::endl;
}
catch (cv::Exception& e)
{
// Gestion de l'exception
std::cout << "Erreur : la matrice n'est pas inversible" << std::endl;
}
return 0;
}
sylvain231 a écrit:Question : pour déduire le theta as-ton besoin du sin et du cos ou seulement de l'un des deux
sylvain231 a écrit:mais je pense que pour gérer à la fois les paraboles "serrées" et les paraboles "plates" il faut séparer en entrée les points "à gauche" du sommet des points "à droite" et ça c'est tout à fait possible car dans mon programme je les connaitrais
std::vector<Point2d> rotatePoint2ds(const std::vector<Point2d>& points, double theta) {
std::vector<Point2d> rotatedPoint2ds;
for (const auto& point : points) {
rotatedPoint2ds.push_back({ point.x * cos(theta) - point.y * sin(theta), point.x * sin(theta) + point.y * cos(theta) });
}
return rotatedPoint2ds;
}
std::vector<Point2d> translatePoint2ds(const std::vector<Point2d>& points, const Point2d& sommet) {
std::vector<Point2d> translatedPoint2ds;
for (const auto& point : points) {
translatedPoint2ds.push_back({point.x - sommet.x, point.y - sommet.y});
}
return translatedPoint2ds;
}
void Parabole::fit2(std::vector<cv::Point2d> points, cv::Point2d sommet) {
this->sommet = sommet;
int n = points.size();
cout << "sommet = " << sommet << endl;
points = translatePoint2ds(points, sommet);
double bestTheta = 0;
double minimum = std::numeric_limits<double>::infinity();
for (double theta = 0; theta <= CV_PI; theta += CV_PI / 1000) {
vector<Point2d> rotated = rotatePoint2ds(points, theta);
double E1 = 0;
for (int i = 0; i < n; i++) {
E1 += pow(rotated[i].y, 2);
}
double E2 = 0;
for (int i = 0; i < n; i++) {
E2 += pow(rotated[i].x, 2) * rotated[i].y;
}
double E3 = 0;
for (int i = 0; i < n; i++) {
E3 += pow(rotated[i].x, 4);
}
double delta = E1 - (E2 / E3);
if (delta < minimum) {
minimum = delta;
bestTheta = theta;
}
}
this->theta_radians = bestTheta;
this->theta = bestTheta * 180 / CV_PI;
vector<Point2d> rotated = rotatePoint2ds(points, bestTheta);
double E2 = 0;
for (int i = 0; i < n; i++) {
E2 += pow(rotated[i].x, 2) * rotated[i].y;
}
double E3 = 0;
for (int i = 0; i < n; i++) {
E3 += pow(rotated[i].x, 4);
}
this->a = E2 / E3;
this->aa = sin(theta_radians) / (4 * a);
this->b = cos(theta_radians) / (4 * a);
cout << "aa" << aa << "b" << b << endl;
cout << "a=" << this->a << endl;
}
sylvain231 a écrit:donc si je comprend bien tu as repris l'ancienne méthode ? mais moi elle ne marchait ni dans la première liste de points ni dans la deuxième, j'ai dû manquer qqch, peux-tu mettre les résultats intermédiaires que je vérifie mes calculs STP ?
sylvain231 a écrit:fais le sur le premier exemple alors où la différence avec ce qu'on devrait trouver est beaucoup plus importante
(...)
vector<Point2d> rotated = rotatePoint2ds(points, theta);
double E1 = 0;
for (int i = 0; i < n; i++) {
E1 += pow(rotated[i].x, 4);
}
double E2 = 0;
for (int i = 0; i < n; i++) {
E2 += pow(rotated[i].x, 2) * rotated[i].y;
}
double E3 = 0;
for (int i = 0; i < n; i++) {
E3 += pow(rotated[i].y, 2);
}
double delta = E1 - (pow(E2,2) / E3);
if (delta < minimum) {
minimum = delta;
bestTheta = theta;
}
}
this->theta_radians = bestTheta;
this->theta = bestTheta * 180 / CV_PI;
vector<Point2d> rotated = rotatePoint2ds(points, bestTheta);
double E2 = 0;
for (int i = 0; i < n; i++) {
E2 += pow(rotated[i].x, 2) * rotated[i].y;
}
double E3 = 0;
for (int i = 0; i < n; i++) {
E3 += pow(rotated[i].y, 2);
}
this->c = E2 / E3;
this->a = sin(theta_radians) *c;
this->b = cos(theta_radians) *c;
cout << "a" << a << "b" << b << endl;
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 39 invités
Tu pars déja ?
Identification
Pas encore inscrit ?
Ou identifiez-vous :