1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Smorkalov
2026-02-11 13:54:39 +03:00
committed by Alexander Smorkalov
468 changed files with 16647 additions and 11284 deletions
+24 -5
View File
@@ -46,6 +46,8 @@
#include <atomic>
#include <limits>
#include <iostream>
#include <algorithm>
#include <cmath>
#include "mathfuncs.hpp"
namespace cv
@@ -1423,12 +1425,21 @@ int cv::solveCubic( InputArray _coeffs, OutputArray _roots )
a3 = coeffs.at<double>(i+3);
}
if( a0 == 0 )
// Fix for Issue #27748: Normalize coefficients to avoid overflow/underflow
// and correctly detect negligible cubic terms.
double max_coeff = std::max({std::abs(a0), std::abs(a1), std::abs(a2), std::abs(a3)});
// If max_coeff is effectively zero, the equation is 0=0
if (max_coeff < std::numeric_limits<double>::epsilon())
return -1;
// Check if the cubic term is negligible relative to the largest coefficient
if( std::abs(a0) < std::numeric_limits<double>::epsilon() * max_coeff )
{
if( a1 == 0 )
if( std::abs(a1) < std::numeric_limits<double>::epsilon() * max_coeff )
{
if( a2 == 0 ) // constant
n = a3 == 0 ? -1 : 0;
if( std::abs(a2) < std::numeric_limits<double>::epsilon() * max_coeff )
n = std::abs(a3) < std::numeric_limits<double>::epsilon() * max_coeff ? -1 : 0;
else
{
// linear equation
@@ -1445,7 +1456,7 @@ int cv::solveCubic( InputArray _coeffs, OutputArray _roots )
d = std::sqrt(d);
double q1 = (-a2 + d) * 0.5;
double q2 = (a2 + d) * -0.5;
if( fabs(q1) > fabs(q2) )
if( std::abs(q1) > std::abs(q2) )
{
x0 = q1 / a1;
x1 = a3 / q1;
@@ -1462,6 +1473,13 @@ int cv::solveCubic( InputArray _coeffs, OutputArray _roots )
else
{
// cubic equation
// Normalize coefficients in-place to prevent overflow/instability
double scale = 1.0 / max_coeff;
a0 *= scale;
a1 *= scale;
a2 *= scale;
a3 *= scale;
a0 = 1./a0;
a1 *= a0;
a2 *= a0;
@@ -1470,6 +1488,7 @@ int cv::solveCubic( InputArray _coeffs, OutputArray _roots )
double Q = (a1 * a1 - 3 * a2) * (1./9);
double R = (a1 * (2 * a1 * a1 - 9 * a2) + 27 * a3) * (1./54);
double Qcubed = Q * Q * Q;
/*
Here we expand expression `Qcubed - R * R` for `d` variable
to reduce common terms `a1^6 / 729` and `-a1^4 * a2 / 81`