Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

`matchShapes` always returns 0

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?

`matchShapes` matchShapes always returns 0

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).