Ask Your Question
3

matchShapes always returns 0

asked 2013-06-06 23:06:28 -0600

Michał Rus gravatar image

updated 2013-06-06 23:10:58 -0600

I'm using matchShapes to recognize some basic contours. However, it's returning 0, no matter what contours I compare...

Template images:

circle cross enter image description here

Examplary input image:

empty triangle, empty circle, cross

The code:

using std::vector;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours(binary, contours, hierarchy,
             CV_RETR_CCOMP, CV_CHAIN_APPROX_TC89_KCOS);

drawContours(binary, contours, -1, Scalar(255, 255, 255));

if (!contours.size()) // avoid sigsegv
    return;

for (int idx = 0; idx >= 0; idx = hierarchy[idx][0]) {
    double bestMatch = INFINITY;
    int bestI = -1;
    for (int i = 0; i < knownContours.size(); i++) {
        vector<Point>& a = knownContours[i].contour;
        vector<Point>& b = contours[idx];
        std::cout << "a.size = " << a.size() << ", b.size = " << b.size() << std::endl;
        double match = matchShapes(b, a, CV_CONTOURS_MATCH_I1, 0);
        std::cout << "idx=" << idx << " ? " << knownContours[i].name << " = " << match << std::endl;
        if (bestI == -1 || match < bestMatch) {
            bestI = i;
            bestMatch = match;
        }
    }
}

(knownContours are obviously initialized with template image data: imread(), then findContours(), finally this->contour = contours[0]).

And resulting output (a fragment):

-- new frame
a.size = 57, b.size = 74
idx=0 ? circle = 0
a.size = 80, b.size = 74
idx=0 ? cross = 0
a.size = 45, b.size = 74
idx=0 ? triangle = 0
a.size = 57, b.size = 60
idx=1 ? circle = 0
a.size = 80, b.size = 60
idx=1 ? cross = 0
a.size = 45, b.size = 60
idx=1 ? triangle = 0

-- new frame
a.size = 57, b.size = 75
idx=0 ? circle = 0
a.size = 80, b.size = 75
idx=0 ? cross = 0
a.size = 45, b.size = 75
idx=0 ? triangle = 0
a.size = 57, b.size = 57
idx=1 ? circle = 0
a.size = 80, b.size = 57
idx=1 ? cross = 0
a.size = 45, b.size = 57
idx=1 ? triangle = 0

-- new frame
a.size = 57, b.size = 76
idx=0 ? circle = 0
a.size = 80, b.size = 76
idx=0 ? cross = 0
a.size = 45, b.size = 76
idx=0 ? triangle = 0
a.size = 57, b.size = 51
idx=1 ? circle = 0
a.size = 80, b.size = 51
idx=1 ? cross = 0
a.size = 45, b.size = 51
idx=1 ? triangle = 0

So the sizes of compared contours differ (so the contours differ), yet match == 0 always. What's going on here?

Edit: OpenCV version is 2.4.9 (cloned & built yesterday).

edit retag flag offensive close merge delete

Comments

trying to run your testcase on 2.4.9 - are you cheating with the flags here, or did you mix up 2.4.5 stuff (again) ?

CV_RETR_CCOMP vs. RETR_CCOMP, CV_CHAIN_APPROX_TC89_KCOS vs. CV_CHAIN_APPROX_TC89_KCOS

can't find any replacement for CV_CONTOURS_MATCH_I1 (that might be a bug,btw), using 1 instead. what's there on your side ?

besides that, similar results(match==0)

diving in, the hu-moments are all 0 already.

berak gravatar imageberak ( 2013-06-07 03:03:11 -0600 )edit

1 answer

Sort by » oldest newest most voted
1

answered 2013-06-07 03:21:48 -0600

berak gravatar image

updated 2013-06-07 04:39:50 -0600

wow, tested your code on 2.4.2:

a.size = 45, b.size = 45
idx=0 ? 0 = 0.026906
a.size = 80, b.size = 45
idx=0 ? 1 = 0.134866
a.size = 57, b.size = 45
idx=0 ? 2 = 0.19551
a.size = 45, b.size = 58
idx=2 ? 0 = 0.159511
a.size = 80, b.size = 58
idx=2 ? 1 = 0.015596
a.size = 57, b.size = 58
idx=2 ? 2 = 0.345972
a.size = 45, b.size = 53
idx=3 ? 0 = 0.199465
a.size = 80, b.size = 53
idx=3 ? 1 = 0.34338
a.size = 57, b.size = 53
idx=3 ? 2 = 0.0130037

the first thing matchShapes() does, is to calculate the hu-moments for both contours, and , as of 2.4.9, they're both all 0.

pretty sure, you found a bug.


Update:

the bug seems to be in :

void cv::HuMoments( const Moments& m, double hu[7] )

m.nu30 , m.nu12, m.nu21, m.nu03, etc are taken for granted, but never got initialized properly

i think, some code-fragment similar to cvGetHuMoments() went awol.

edit flag offensive delete link more

Comments

Ahh... So the solution would be to use stable? 2.4.5? Have you filed a bug report already?

Michał Rus gravatar imageMichał Rus ( 2013-06-07 07:38:01 -0600 )edit

yes, working on a patch.

2.4.5 is definitely more stable, but another 350 mb download ;)

berak gravatar imageberak ( 2013-06-07 08:41:06 -0600 )edit

would you do me the favor of trying my patch for 2.4.9 ?

at least your code shows the same results as in 2.4.2 now.

berak gravatar imageberak ( 2013-06-07 11:32:49 -0600 )edit

@berak It works. :) Thanks!

Michał Rus gravatar imageMichał Rus ( 2013-06-07 12:40:21 -0600 )edit

nice, thanks for testing ;)

will make a pull request of it tomorrow !

berak gravatar imageberak ( 2013-06-07 13:15:32 -0600 )edit

i'm still confused about the flags. what did you use as replacement for CV_CONTOURS_MATCH_I1 ?

i can't find anything in 2.4.9

berak gravatar imageberak ( 2013-06-08 06:36:07 -0600 )edit

ah, cool, pull request accepted/closed.

so, it won't happen to other people from now.

thanks, again, for hinting out the bug.

berak gravatar imageberak ( 2013-06-11 16:44:03 -0600 )edit

Question Tools

Stats

Asked: 2013-06-06 23:06:28 -0600

Seen: 5,372 times

Last updated: Jun 07 '13