La méthode ici :
superieur/regression-parabolique-non-triviale-t278846-240.html#p1549234
On obtient cette équation de parabole :
double E(vector <Point2d> points, int a, int b) {
double res = 0;
int n = points.size();
for (int i = 0; i < n; i++) {
res += pow(points[i].x, a) * pow(points[i].y, b);
}
return res / n;
}
void Parabole::fit(std::vector<cv::Point2d> points, cv::Point2d sommet) {
this->sommet = sommet;
int n = points.size();
cout << "sommet = " << sommet << endl;
points = translatePoint2ds(points, sommet);
double E40 = E(points, 4, 0);
double E31 = E(points, 3, 1);
double E22 = E(points, 2, 2);
double E13 = E(points, 1, 3);
double E04 = E(points, 0, 4);
double E21 = E(points, 2, 1);
double E30 = E(points, 3, 0);
double E12 = E(points, 1, 2);
double E03 = E(points, 0, 3);
double E02 = E(points, 0, 2);
double E11 = E(points, 1, 1);
double E20 = E(points, 2, 0);
double minimum = std::numeric_limits<double>::infinity();
for (double theta = 0; theta <= CV_PI; theta += CV_PI / 1000) {
double c = cos(theta);
double s = sin(theta);
double alpha = E40 * pow(c, 4) - 4 * E31 * pow(c, 3) * s + 6 * E22 * pow(c, 2) * pow(s, 2)
- 4 * E13 * c * pow(s, 3) + E04 * pow(s, 4);
double beta = E21 * pow(c, 3) + (E30 - 2 * E12) * pow(c, 2) * s +
(E03 - 2*E21) * c * pow(s, 2) + E12 * pow(s, 3);
double gamma = E02 * pow(c, 2) + 2 * E11 * c * s + E20 * pow(s, 2);
double Mmin = 0.5 * (alpha + gamma - sqrt(pow(alpha - gamma, 2) + 4 * pow(beta, 2)));
if (Mmin < minimum) {
minimum = Mmin;
this->theta_radians = theta;
}
}
double c = cos(this->theta_radians);
double s = sin(this->theta_radians);
double alpha = E40 * pow(c, 4) - 4 * E31 * pow(c, 3) * s + 6 * E22 * pow(c, 2) * pow(s, 2)
- 4 * E13 * c * pow(s, 3) + E04 * pow(s, 4);
double beta = E21 * pow(c, 3) + (E30 - 2 * E12) * pow(c, 2) * s +
(E03 - 2*E21) * c * pow(s, 2) + E12 * pow(s, 3);
double gamma = E02 * pow(c, 2) + 2 * E11 * c * s + E20 * pow(s, 2);
this->a = (1 / (2 * beta)) * (alpha - gamma - sqrt(pow(alpha - gamma, 2) + 4 * pow(beta, 2)));
this->theta = 180 * theta_radians / CV_PI;
}
void Parabole::fit(std::vector<cv::Point2d> points, cv::Point2d sommet) {
this->sommet = sommet;
int n = points.size();
cout << "sommet = " << sommet << endl;
points = translatePoint2ds(points, sommet);
double E40 = E(points, 4, 0);
double E31 = E(points, 3, 1);
double E22 = E(points, 2, 2);
double E13 = E(points, 1, 3);
double E04 = E(points, 0, 4);
double E21 = E(points, 2, 1);
double E30 = E(points, 3, 0);
double E12 = E(points, 1, 2);
double E03 = E(points, 0, 3);
double E02 = E(points, 0, 2);
double E11 = E(points, 1, 1);
double E20 = E(points, 2, 0);
double minimum = std::numeric_limits<double>::infinity();
for (double theta = 0; theta <= CV_PI; theta += CV_PI / 1000) {
points = rotatePoint2ds(points, theta);
double alpha = E40;
double beta = E21;
double gamma = E02;
double Mmin = 1 / 2 / beta * (-alpha + gamma + sqrt(pow(alpha - gamma, 2) + 4 * pow(beta, 2)));
if (Mmin < minimum) {
minimum = Mmin;
this->theta_radians = theta;
}
}
double c = cos(this->theta_radians);
double s = sin(this->theta_radians);
double alpha = E40 * pow(c, 4) - 4 * E31 * pow(c, 3) * s + 6 * E22 * pow(c, 2) * pow(s, 2)
- 4 * E13 * c * pow(s, 3) + E04 * pow(s, 4);
double beta = E21 * pow(c, 3) + (E30 - 2 * E12) * pow(c, 2) * s +
(E03 - 2*E21) * c * pow(s, 2) + E12 * pow(s, 3);
double gamma = E02 * pow(c, 2) + 2 * E11 * c * s + E20 * pow(s, 2);
this->a = (1 / (2 * beta)) * (gamma - alpha + sqrt(pow(alpha - gamma, 2) + 4 * pow(beta, 2)));
this->theta = 180 * theta_radians / CV_PI;
}
void Parabole::fit(std::vector<cv::Point2d> points, cv::Point2d sommet) {
this->sommet = sommet;
int n = points.size();
cout << "sommet = " << sommet << endl;
points = translatePoint2ds(points, sommet);
double E40 = E(points, 4, 0);
double E31 = E(points, 3, 1);
double E22 = E(points, 2, 2);
double E13 = E(points, 1, 3);
double E04 = E(points, 0, 4);
double E21 = E(points, 2, 1);
double E30 = E(points, 3, 0);
double E12 = E(points, 1, 2);
double E03 = E(points, 0, 3);
double E02 = E(points, 0, 2);
double E11 = E(points, 1, 1);
double E20 = E(points, 2, 0);
double minimum = std::numeric_limits<double>::infinity();
for (double theta = 0; theta <= CV_PI; theta += CV_PI / 1000) {
vector<Point2d> points2 = rotatePoint2ds(points, theta);
double alpha = E(points2, 4, 0);
double beta = E(points2, 2, 1);
double gamma = E(points2, 0, 2);
double Mmin = 1 / 2 / beta * (-alpha + gamma + sqrt(pow(alpha - gamma, 2) + 4 * pow(beta, 2)));
if (Mmin < minimum) {
minimum = Mmin;
this->theta_radians = theta;
}
}
vector<Point2d> points2 = rotatePoint2ds(points, this->theta_radians);
double alpha = E(points2, 4, 0);
double beta = E(points2, 2, 1);
double gamma = E(points2, 0, 2);
this->a = (1 / (2 * beta)) * (gamma - alpha + sqrt(pow(alpha - gamma, 2) + 4 * pow(beta, 2)));
this->theta = 180 * theta_radians / CV_PI;
}
leon1789 a écrit: minimiser alpha + gamma - sqrt((alpha- gamma)^2+4 *beta^2)
double Mmin = alpha + gamma - sqrt(pow(alpha - gamma, 2) + 4 * pow(beta, 2)) ;
sylvain231 a écrit:je trouve :
theta = 50.04, theta_radians= 0.873363 a = -1.98229 sommet = [191, 291]
void Parabole::draw(Mat& img, cv::Vec3b color) {
// Itérer sur chaque pixel
for (double y = 0; y < img.rows; y += 0.1) {
for (double x = 0; x < img.cols; x += 0.1) {
// Calculer X' et Y'
double X_prime = x - sommet.x;
double Y_prime = y - sommet.y;
// Calculer la valeur de l'équation de la parabole
double val;
val = a * pow(cos(this->theta_radians) * X_prime + sin(this->theta_radians) * Y_prime, 2)
- sin(this->theta_radians) * X_prime - cos(this->theta_radians) * Y_prime;
// }
// Si val est proche de 0, colorer le pixel
if (fabs(val) < 0.5) { // Vous pouvez ajuster la tolérance
img.at<cv::Vec3b>(y, x) = color; // Par exemple, en blanc
}
}
}
}
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 8 invités
Tu pars déja ?
Identification
Pas encore inscrit ?
Ou identifiez-vous :