From 800da724a3390804b38e118a52b709ca2f157b65 Mon Sep 17 00:00:00 2001 From: Jasper Shemilt Date: Mon, 2 Oct 2017 17:56:08 +0100 Subject: [PATCH] Fix Transposed eigenvals and vecs. Didn't notice at first --- modules/imgproc/src/shapedescr.cpp | 38 +++++++++++++++++++------------------- samples/cpp/fitellipse.cpp | 12 +++++++++--- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/modules/imgproc/src/shapedescr.cpp b/modules/imgproc/src/shapedescr.cpp index a145310..9fe1498 100644 --- a/modules/imgproc/src/shapedescr.cpp +++ b/modules/imgproc/src/shapedescr.cpp @@ -544,15 +544,15 @@ cv::RotatedRect cv::fitEllipseAMS( InputArray _points ) // Select the eigen vector {a,b,c,d,e} which has the lowest eigenvalue int minpos = 0; double normi, normEVali, normMinpos, normEValMinpos; - normMinpos = sqrt(eVec.at(0,minpos)*eVec.at(0,minpos) + eVec.at(1,minpos)*eVec.at(1,minpos) + \ - eVec.at(2,minpos)*eVec.at(2,minpos) + eVec.at(3,minpos)*eVec.at(3,minpos) + \ - eVec.at(4,minpos)*eVec.at(4,minpos) ); - normEValMinpos = eVal.at(0,minpos) * normMinpos; + normMinpos = sqrt(eVec.at(minpos,0)*eVec.at(minpos,0) + eVec.at(minpos,1)*eVec.at(minpos,1) + \ + eVec.at(minpos,2)*eVec.at(minpos,2) + eVec.at(minpos,3)*eVec.at(minpos,3) + \ + eVec.at(minpos,4)*eVec.at(minpos,4) ); + normEValMinpos = eVal.at(minpos,0) * normMinpos; for (i=1; i<5; i++) { - normi = sqrt(eVec.at(0,i)*eVec.at(0,i) + eVec.at(1,i)*eVec.at(1,i) + \ - eVec.at(2,i)*eVec.at(2,i) + eVec.at(3,i)*eVec.at(3,i) + \ - eVec.at(4,i)*eVec.at(4,i) ); - normEVali = eVal.at(0,i) * normi; + normi = sqrt(eVec.at(i,0)*eVec.at(i,0) + eVec.at(i,1)*eVec.at(i,1) + \ + eVec.at(i,2)*eVec.at(i,2) + eVec.at(i,3)*eVec.at(i,3) + \ + eVec.at(i,4)*eVec.at(i,4) ); + normEVali = eVal.at(i,0) * normi; if (normEVali < normEValMinpos) { minpos = i; normMinpos=normi; @@ -560,11 +560,11 @@ cv::RotatedRect cv::fitEllipseAMS( InputArray _points ) } }; - pVec(0) =eVec.at(0,minpos) / normMinpos; - pVec(1) =eVec.at(1,minpos) / normMinpos; - pVec(2) =eVec.at(2,minpos) / normMinpos; - pVec(3) =eVec.at(3,minpos) / normMinpos; - pVec(4) =eVec.at(4,minpos) / normMinpos; + pVec(0) =eVec.at(minpos,0) / normMinpos; + pVec(1) =eVec.at(minpos,1) / normMinpos; + pVec(2) =eVec.at(minpos,2) / normMinpos; + pVec(3) =eVec.at(minpos,3) / normMinpos; + pVec(4) =eVec.at(minpos,4) / normMinpos; coeffs(0) =pVec(0) ; coeffs(1) =pVec(1) ; @@ -715,19 +715,19 @@ cv::RotatedRect cv::fitEllipseDirect( InputArray _points ) // Select the eigen vector {a,b,c} which satisfies 4ac-b^2 > 0 double cond[3]; - cond[0]=(4.0 * eVec.at(0,0) * eVec.at(2,0) - eVec.at(1,0) * eVec.at(1,0)); - cond[1]=(4.0 * eVec.at(0,1) * eVec.at(2,1) - eVec.at(1,1) * eVec.at(1,1)); - cond[2]=(4.0 * eVec.at(0,2) * eVec.at(2,2) - eVec.at(1,2) * eVec.at(1,2)); + cond[0]=(4.0 * eVec.at(0,0) * eVec.at(0,2) - eVec.at(0,1) * eVec.at(0,1)); + cond[1]=(4.0 * eVec.at(1,0) * eVec.at(1,2) - eVec.at(1,1) * eVec.at(1,1)); + cond[2]=(4.0 * eVec.at(2,0) * eVec.at(2,2) - eVec.at(2,1) * eVec.at(2,1)); if (cond[0](0,i)*eVec.at(0,i) + eVec.at(1,i)*eVec.at(1,i) + eVec.at(2,i)*eVec.at(2,i)); - if (((eVec.at(0,i)<0.0 ? -1 : 1) * (eVec.at(1,i)<0.0 ? -1 : 1) * (eVec.at(2,i)<0.0 ? -1 : 1)) <= 0.0) { + double norm = std::sqrt(eVec.at(i,0)*eVec.at(i,0) + eVec.at(i,1)*eVec.at(i,1) + eVec.at(i,2)*eVec.at(i,2)); + if (((eVec.at(i,0)<0.0 ? -1 : 1) * (eVec.at(i,1)<0.0 ? -1 : 1) * (eVec.at(i,2)<0.0 ? -1 : 1)) <= 0.0) { norm=-1.0*norm; } - pVec(0) =eVec.at(0,i)/norm; pVec(1) =eVec.at(1,i)/norm;pVec(2) =eVec.at(2,i)/norm; + pVec(0) =eVec.at(i,0)/norm; pVec(1) =eVec.at(i,1)/norm;pVec(2) =eVec.at(i,2)/norm; // Q = (TM . pVec)/Ts; Q(0,0) = (TM(0,0)*pVec(0) +TM(0,1)*pVec(1) +TM(0,2)*pVec(2) )/Ts; diff --git a/samples/cpp/fitellipse.cpp b/samples/cpp/fitellipse.cpp index 0c1049f..2948449 100644 --- a/samples/cpp/fitellipse.cpp +++ b/samples/cpp/fitellipse.cpp @@ -282,15 +282,21 @@ void processImage(int /*h*/, void*) } if (fitEllipseQ) { box = fitEllipse(pts); - if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 ){continue;}; + if( MAX(box.size.width, box.size.height) > MIN(box.size.width, box.size.height)*30 || + MAX(box.size.width, box.size.height) <= 0 || + MIN(box.size.width, box.size.height) <= 0){continue;}; } if (fitEllipseAMSQ) { boxAMS = fitEllipseAMS(pts); - if( MAX(boxAMS.size.width, boxAMS.size.height) > MIN(boxAMS.size.width, boxAMS.size.height)*30 ){continue;}; + if( MAX(boxAMS.size.width, boxAMS.size.height) > MIN(boxAMS.size.width, boxAMS.size.height)*30 || + MAX(box.size.width, box.size.height) <= 0 || + MIN(box.size.width, box.size.height) <= 0){continue;}; } if (fitEllipseDirectQ) { boxDirect = fitEllipseDirect(pts); - if( MAX(boxDirect.size.width, boxDirect.size.height) > MIN(boxDirect.size.width, boxDirect.size.height)*30 ){continue;}; + if( MAX(boxDirect.size.width, boxDirect.size.height) > MIN(boxDirect.size.width, boxDirect.size.height)*30 || + MAX(box.size.width, box.size.height) <= 0 || + MIN(box.size.width, box.size.height) <= 0 ){continue;}; } if (fitEllipseQ) { -- 2.7.4