9 #include <eigen3/Eigen/Dense> 20 return fabs(d) <= std::numeric_limits<T>::epsilon();
28 while(a >= 2.*M_PI) a -= 2.*M_PI;
29 while(a < 0.) a += 2.*M_PI;
53 const std::vector<cv::Point2f> &points,
Ellipse &ellipse)
60 double minx=10000, maxx=0, miny=10000, maxy=0;
61 double minGradPoints=10000,maxGradPoints=0;
63 for(
unsigned i=0; i<points.size(); i++)
65 const cv::Point2f &pt = points[i];
67 if(pt.x < minx) minx=pt.x;
68 if(pt.y < miny) miny=pt.y;
69 if(pt.x > maxx) maxx=pt.x;
70 if(pt.y > maxy) maxy=pt.y;
71 float a = im_dx(pt.y,pt.x);
72 float b = im_dy(pt.y,pt.x);
73 float grad = sqrt(a*a + b*b);
74 if(minGradPoints > grad) minGradPoints = grad;
75 if(grad > maxGradPoints) maxGradPoints = grad;
78 double gradThreshold = (minGradPoints + (maxGradPoints - minGradPoints)/2)/2;
86 short min_y = (short)(miny-rand);
87 short max_y = (short)(maxy+rand);
88 short min_x = (short)(minx-rand);
89 short max_x = (short)(maxx+rand);
90 if (min_y < 0) min_y = 0;
91 if (max_y >= im_dx.rows) max_y = (short)im_dx.rows-1;
92 if (min_x < 0) min_x = 0;
93 if (max_x >= im_dx.cols) max_x = (short)im_dx.cols-1;
95 for(
short j=min_y; j < max_y; j++)
97 for(
short i=min_x; i < max_x; i++)
100 float b = im_dy(j,i);
101 float grad = sqrt(a*a + b*b);
102 if(gradThreshold < grad &&
103 ellipse.
insideEllipse(ellipse.
a+ellipseRand,ellipse.
b+ellipseRand,ellipse.
x,ellipse.
y, ellipse.
phi,i,j) &&
104 !ellipse.
insideEllipse(ellipse.
a-ellipseRand,ellipse.
b-ellipseRand,ellipse.
x,ellipse.
y, ellipse.
phi,i,j))
125 lengths+= sqrt(a*a + b*b);
128 double ss = sqrt(2.) / (lengths/
pointsToUse.size());
130 H << ss, 0, -ss*mx, 0, ss, -ss*my, 0, 0, 1;
131 Eigen::Matrix3d Hinv = H.inverse();
132 Eigen::Matrix3d HinvT = Hinv.transpose();
186 Eigen::MatrixXd M = Eigen::MatrixXd::Zero(5,5);
187 Eigen::VectorXd E = Eigen::VectorXd::Zero(5);
188 Eigen::VectorXd Kprima(5);
189 Eigen::MatrixXd res1(5,5);
192 std::vector<Eigen::Vector3d> tangentLines((
unsigned)
pointsToUse.size());
199 float a = im_dx((
short)pt.y,(
short)pt.x);
200 float b = im_dy((
short)pt.y,(
short)pt.x);
201 float grad = sqrt(a*a + b*b);
204 li << double(im_dx((
short)pt.y,(
short)pt.x)), double(im_dy((
short)pt.y,(
short)pt.x)),
205 -( double(im_dx((
short)pt.y,(
short)pt.x))*pt.x + double(im_dy((
short)pt.y,(
short)pt.x))*pt.y );
214 tangentLines[i] = li;
216 double weight = grad*grad;
217 Kprima[0] = li[0]*li[0];
218 Kprima[1] = li[0]*li[1];
219 Kprima[2] = li[1]*li[1];
220 Kprima[3] = li[0]*li[2];
221 Kprima[4] = li[1]*li[2];
223 res1 = weight*Kprima*Kprima.transpose();
226 Kprima[0] *= -weight*li[2]*li[2];
227 Kprima[1] *= -weight*li[2]*li[2];
228 Kprima[2] *= -weight*li[2]*li[2];
229 Kprima[3] *= -weight*li[2]*li[2];
230 Kprima[4] *= -weight*li[2]*li[2];
238 Eigen::MatrixXd MT(5,5);
241 Eigen::MatrixXd MPerMT(5,5), MPerMTinv(5,5);
244 MPerMTinv = MPerMT.inverse();
245 MPerMT = MPerMTinv*MT;
247 Eigen::VectorXd params(5);
250 Eigen::Matrix3d CNorm;
251 CNorm << params[0], params[1]/2., params[3]/2.,
252 params[1]/2., params[2], params[4]/2.,
253 params[3]/2., params[4]/2., 1;
256 Eigen::Matrix3d CNormMalHInv;
257 CNormMalHInv = Hinv*CNorm*HinvT;
262 double dSumDistance=0;
263 Eigen::Vector3d pole;
267 const Eigen::Vector3d &l = tangentLines[i];
271 double x0 = pole[0]/pole[2];
272 double y0 = pole[1]/pole[2];
275 double d = abs(l[0] * x0 + l[1] * y0 + l[2]) / sqrt(a*a+b*b);
285 C = CNormMalHInv.inverse();
287 double Ac,Bc,Cc,Dc,Ec,Fc;
307 : id(0),
x(0),
y(0), a(0), b(0), phi(0), fit_error(0.), support(0.), a2(0), a4(0), b2(0), b4(0), x2(0), y2(0)
311 :
id(e.
id),
x(e.
x),
y(e.
y),
a(e.
a),
b(e.
b),
phi(e.
phi),
fit_error(e.
fit_error),
support(e.
support),
a2(e.
a2),
a4(e.
a4),
b2(e.
b2),
b4(e.
b4),
x2(e.
x2),
y2(e.
y2){
315 x = _x,
y = _y,
a = _a,
b = _b,
phi = _phi;
331 a = double(rect.size.width)/2.;
332 b = double(rect.size.height)/2.;
349 double co = cos(-
phi), si = sin(-
phi), n,
d, dist;
356 inl_idx.resize(points.size());
358 for(z=0; z<points.size(); z++)
368 q.x = co*p.x - si*p.y;
369 q.y = si*p.x + co*p.y;
393 if (nbInl>0 && !
isZero(circumference))
396 support = (double)nbInl / circumference;
409 r.center.x =
x, r.center.y =
y;
410 r.size.width =
a*2., r.size.height =
b*2.;
411 r.angle =
phi*180./M_PI;
420 double BcBcAcCc = (Bc*Bc - Ac*Cc);
424 double x0 = (Cc*Dc - Bc*Ec) / BcBcAcCc;
425 double y0 = (Ac*Ec - Bc*Dc) / BcBcAcCc;
426 double a0, a0_2, b0, b0_2, phi0;
428 double SqrAcCc4BcBc = d*d + 4*Bc*Bc;
429 if (SqrAcCc4BcBc < 0) {
432 a0_2 = (2*(Ac*Ec*Ec + Cc*Dc*Dc + Fc*Bc*Bc - 2*Bc*Dc*Ec - Ac*Cc*Fc)) / ((Bc*Bc - Ac*Cc)*((sqrt(SqrAcCc4BcBc)) - (Ac+Cc)));
433 b0_2 = (2*(Ac*Ec*Ec + Cc*Dc*Dc + Fc*Bc*Bc - 2*Bc*Dc*Ec - Ac*Cc*Fc)) / ((Bc*Bc - Ac*Cc)*(-(sqrt(SqrAcCc4BcBc)) - (Ac+Cc)));
434 if ((a0_2 < 0) || (b0_2 < 0)) {
448 double z = (Ac-Cc) / (2*Bc);
450 phi0=0.5*(atan(1./z));
454 phi0=M_PI_2 + 0.5*(atan(1./z));
481 return M_PI*(1.5*(a +
b) - sqrt(a*b));
490 double dx = ((_x - _x0)*cos(_phi) + (_y-_y0)*sin(_phi)) / _a;
491 double dy = (-(_x - _x0)*sin(_phi) + (_y-_y0)*cos(_phi)) / _b;
492 double distance = dx * dx + dy * dy;
493 return (distance < 1.0) ? 1 : 0;
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val)
double scaleAngle_0_2pi(double a)
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const
EllipseRefinement(const Parameter &_param=Parameter())
TFSIMD_FORCE_INLINE const tfScalar & y() const
double ellipseCircumference(double a, double b)
bool refine(const cv::Mat_< short > &im_dx, const cv::Mat_< short > &im_dy, const std::vector< cv::Point2f > &points, Ellipse &ellipse)
TFSIMD_FORCE_INLINE const tfScalar & x() const
void setEllipse(const double &_x, const double &_y, const double &_a, const double &_b, const double &_phi)
TFSIMD_FORCE_INLINE const tfScalar & z() const
void get(cv::RotatedRect &r)
bool computeAndSetGeomFromConic(double A, double B, double C, double D, double E, double F)
bool insideEllipse(double _a, double _b, double _x0, double _y0, double _phi, double _x, double _y) const
unsigned ellipseSupport(const std::vector< cv::Point2f > &points, double inl_dist, std::vector< bool > &inl_idx)
std::vector< cv::Point2d > pointsToUse