From d33d37ffd9af0367aa3ee637a3f4252ac1271930 Mon Sep 17 00:00:00 2001 From: Tetragramm Date: Wed, 4 Jan 2017 18:38:46 -0600 Subject: [PATCH 1/2] Add check for all zero moments. If one of the shapes is empty, the match would return zero distance between the shapes even when the other one had content. It now returns DBL_MAX if no moments had value. --- modules/imgproc/src/matchcontours.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/imgproc/src/matchcontours.cpp b/modules/imgproc/src/matchcontours.cpp index 1a371677bf..f848bd59a8 100644 --- a/modules/imgproc/src/matchcontours.cpp +++ b/modules/imgproc/src/matchcontours.cpp @@ -50,6 +50,7 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou double eps = 1.e-5; double mmm; double result = 0; + bool anyResults = false; HuMoments( moments(contour1), ma ); HuMoments( moments(contour2), mb ); @@ -80,6 +81,7 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou ama = 1. / (sma * log10( ama )); amb = 1. / (smb * log10( amb )); result += fabs( -ama + amb ); + anyResults = true; } } break; @@ -108,6 +110,7 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou ama = sma * log10( ama ); amb = smb * log10( amb ); result += fabs( -ama + amb ); + anyResults = true; } } break; @@ -138,6 +141,7 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou mmm = fabs( (ama - amb) / ama ); if( result < mmm ) result = mmm; + anyResults = true; } } break; @@ -145,6 +149,9 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou CV_Error( CV_StsBadArg, "Unknown comparison method" ); } + if (!anyResults) + result = DBL_MAX; + return result; } From 7cc0b0f93ea3fa8131b478bc9483199ae933ebe7 Mon Sep 17 00:00:00 2001 From: Tetragramm Date: Tue, 10 Jan 2017 21:38:31 -0600 Subject: [PATCH 2/2] Add case including both moments empty. --- modules/imgproc/src/matchcontours.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/modules/imgproc/src/matchcontours.cpp b/modules/imgproc/src/matchcontours.cpp index f848bd59a8..2a0c5df330 100644 --- a/modules/imgproc/src/matchcontours.cpp +++ b/modules/imgproc/src/matchcontours.cpp @@ -50,7 +50,7 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou double eps = 1.e-5; double mmm; double result = 0; - bool anyResults = false; + bool anyA = false, anyB = false; HuMoments( moments(contour1), ma ); HuMoments( moments(contour2), mb ); @@ -63,6 +63,11 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou double ama = fabs( ma[i] ); double amb = fabs( mb[i] ); + if (ama > 0) + anyA = true; + if (amb > 0) + anyB = true; + if( ma[i] > 0 ) sma = 1; else if( ma[i] < 0 ) @@ -81,7 +86,6 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou ama = 1. / (sma * log10( ama )); amb = 1. / (smb * log10( amb )); result += fabs( -ama + amb ); - anyResults = true; } } break; @@ -92,6 +96,11 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou double ama = fabs( ma[i] ); double amb = fabs( mb[i] ); + if (ama > 0) + anyA = true; + if (amb > 0) + anyB = true; + if( ma[i] > 0 ) sma = 1; else if( ma[i] < 0 ) @@ -110,7 +119,6 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou ama = sma * log10( ama ); amb = smb * log10( amb ); result += fabs( -ama + amb ); - anyResults = true; } } break; @@ -121,6 +129,11 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou double ama = fabs( ma[i] ); double amb = fabs( mb[i] ); + if (ama > 0) + anyA = true; + if (amb > 0) + anyB = true; + if( ma[i] > 0 ) sma = 1; else if( ma[i] < 0 ) @@ -141,7 +154,6 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou mmm = fabs( (ama - amb) / ama ); if( result < mmm ) result = mmm; - anyResults = true; } } break; @@ -149,7 +161,10 @@ double cv::matchShapes(InputArray contour1, InputArray contour2, int method, dou CV_Error( CV_StsBadArg, "Unknown comparison method" ); } - if (!anyResults) + //If anyA and anyB are both true, the result is correct. + //If anyA and anyB are both false, the distance is 0, perfect match. + //If only one is true, then it's a false 0 and return large error. + if (anyA != anyB) result = DBL_MAX; return result;