Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

knnMatch() returning strange match counts and indices

In the match object populated by knnMatch() (K=1, either unique or not) I get strange pattern of match counts for each entry returned - the counts order is typically [x, y, 7, 8, x, y, 7, 8, ...] (x/y typically 0 or 1 which make sense). Once in a while wild numbers (e.g. 8521267) are set there.

In addition, the indices of the first matches are also often wild numbers, built from 0xEEEEEEEE/0xABABABAB/0xCDCDCDCD, which seem to indicate they point to some wrong heap areas.

I include a snapshot of the compact returned values from VS 2012 and the test code I used, still before meaningful code has been run.

Hope someone can explain this, point to something wrong I did, or is that a real bug? Any workaround in this case?

I was also suspecting a possible incompatibility between STL versions between my build and the OpenCV library, but I didn't see such issues when searching.

--- Returned values ---
-       matches { size=128 }    ::vector<std::vector<cv::DMatch,std::allocator<cv::DMatch> >,std::allocator<std::vector<cv::DMatch,std::allocator<cv::DMatch> > > >
        [size]  128 __int64
        [capacity]  128 __int64
+       [0] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [1] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [2] { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [3] { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [4] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [5] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [6] { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [7] { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [8] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [9] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [10]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [11]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [12]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [13]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [14]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [15]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [16]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [17]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [18]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [19]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [20]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [21]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [22]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [23]    { size=8521267 }    std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [24]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [25]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
...
--- Test Function (based on sample code) ---

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/nonfree/nonfree.hpp"
using namespace cv;

int TestKeypointMatching(const std::string & fname1, const std::string & fname2)
{
    Mat img1 = imread(fname1, CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = imread(fname2, CV_LOAD_IMAGE_GRAYSCALE);
    if(img1.empty() || img2.empty())
    {
        printf("Can't read one of the images\n");
        return -1;
    }

    // detecting keypoints
    // Ptr<featuredetector> detector0 = FeatureDetector::create("SurfFeatureDetector");
    SurfFeatureDetector detector(400);
    vector<keypoint> keypoints1, keypoints2;
    detector.detect(img1, keypoints1);
    detector.detect(img2, keypoints2);

    // computing descriptors

    int descVer = 2;
    Feature2D *pExtractor = NULL;

    if (descVer == 1) {  // SURF.
        // SurfDescriptorExtractor extractor;
        pExtractor = new SurfDescriptorExtractor();
    } else if (descVer == 2) {  // SIFT.
        pExtractor = new  SIFT(500, 3, 0.03, 10.0, 1.0);
    }

    Mat descriptors1, descriptors2;
    pExtractor->compute(img1, keypoints1, descriptors1);
    pExtractor->compute(img2, keypoints2, descriptors2);
    // delete pExtractor;  NOTE: this prompts heap corruption exception ?!


    // matching descriptors
    DescriptorMatcher *pMatcher = NULL;
    vector<dmatch> matches;

    int matcherVer = 2;  // Note: error happens for both 1 and 2.

    // BFMatcher matcher;
    if (matcherVer == 1) {  // BFMatcher (Brute Force).
        // SurfDescriptorExtractor extractor;
        pMatcher = new BFMatcher();
    } else if (descVer == 2) {  // BFMatcher (Brute Force) unique knnMatch.
        pMatcher = new BFMatcher(NORM_L2, true);
    }

    int matchType = 2;  // Note: plain match (1) works fine.
    if (matchType == 1) {  // Plain match().
        pMatcher->match(descriptors1, descriptors2, matches);

        // drawing the results
        namedWindow("matches", 1);
        Mat img_matches;
        drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
        imshow("matches", img_matches);
        waitKey(0);
    } else if (matchType == 2) {  // knnMatch().
        std::vector<std::vector<dmatch> > matches;
        pMatcher->knnMatch(descriptors1, descriptors2, matches, 1);

        Mat img_matches;
        drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
        imshow("matches", img_matches);
        waitKey(0);
    }
}

knnMatch() returning strange match counts and indices

In the match object populated by knnMatch() (K=1, either unique or not) I get strange pattern of match counts for each entry returned - the counts order is typically [x, y, 7, 8, x, y, 7, 8, ...] (x/y typically 0 or 1 which make sense). Once in a while wild numbers (e.g. 8521267) are set there.

In addition, the indices of the first matches are also often wild numbers, built from 0xEEEEEEEE/0xABABABAB/0xCDCDCDCD, which seem to indicate they point to some wrong heap areas.

I include a snapshot of the compact returned values from VS 2012 and the test code I used, still before meaningful code has been run.

Hope someone can explain this, point to something wrong I did, or is that a real bug? Any workaround in this case?

I was also suspecting a possible incompatibility between STL versions between my build and the OpenCV library, but I didn't see such issues when searching.

This happens with 2.4.6

--- Returned values ---
-       matches { size=128 }    ::vector<std::vector<cv::DMatch,std::allocator<cv::DMatch> >,std::allocator<std::vector<cv::DMatch,std::allocator<cv::DMatch> > > >
        [size]  128 __int64
        [capacity]  128 __int64
+       [0] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [1] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [2] { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [3] { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [4] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [5] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [6] { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [7] { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [8] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [9] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [10]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [11]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [12]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [13]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [14]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [15]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [16]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [17]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [18]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [19]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [20]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [21]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [22]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [23]    { size=8521267 }    std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [24]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [25]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
...
 
--- Test Function (based on sample code) ---

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/nonfree/nonfree.hpp"
using namespace cv;

int TestKeypointMatching(const std::string & fname1, const std::string & fname2)
{
    Mat img1 = imread(fname1, CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = imread(fname2, CV_LOAD_IMAGE_GRAYSCALE);
    if(img1.empty() || img2.empty())
    {
        printf("Can't read one of the images\n");
        return -1;
    }

    // detecting keypoints
    // Ptr<featuredetector> detector0 = FeatureDetector::create("SurfFeatureDetector");
    SurfFeatureDetector detector(400);
    vector<keypoint> keypoints1, keypoints2;
    detector.detect(img1, keypoints1);
    detector.detect(img2, keypoints2);

    // computing descriptors

    int descVer = 2;
    Feature2D *pExtractor = NULL;

    if (descVer == 1) {  // SURF.
        // SurfDescriptorExtractor extractor;
        pExtractor = new SurfDescriptorExtractor();
    } else if (descVer == 2) {  // SIFT.
        pExtractor = new  SIFT(500, 3, 0.03, 10.0, 1.0);
    }

    Mat descriptors1, descriptors2;
    pExtractor->compute(img1, keypoints1, descriptors1);
    pExtractor->compute(img2, keypoints2, descriptors2);
    // delete pExtractor;  NOTE: this prompts heap corruption exception ?!


    // matching descriptors
    DescriptorMatcher *pMatcher = NULL;
    vector<dmatch> matches;

    int matcherVer = 2;  // Note: error happens for both 1 and 2.

    // BFMatcher matcher;
    if (matcherVer == 1) {  // BFMatcher (Brute Force).
        // SurfDescriptorExtractor extractor;
        pMatcher = new BFMatcher();
    } else if (descVer == 2) {  // BFMatcher (Brute Force) unique knnMatch.
        pMatcher = new BFMatcher(NORM_L2, true);
    }

    int matchType = 2;  // Note: plain match (1) works fine.
    if (matchType == 1) {  // Plain match().
        pMatcher->match(descriptors1, descriptors2, matches);

        // drawing the results
        namedWindow("matches", 1);
        Mat img_matches;
        drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
        imshow("matches", img_matches);
        waitKey(0);
    } else if (matchType == 2) {  // knnMatch().
        std::vector<std::vector<dmatch> > matches;
        pMatcher->knnMatch(descriptors1, descriptors2, matches, 1);

        Mat img_matches;
        drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
        imshow("matches", img_matches);
        waitKey(0);
    }
}

knnMatch() returning strange match counts and indices

In the match object populated by knnMatch() (K=1, either unique or not) I get strange pattern of match counts for each entry returned - the counts order is typically [x, y, 7, 8, x, y, 7, 8, ...] (x/y typically 0 or 1 which make sense). Once in a while wild numbers (e.g. 8521267) are set there.

In addition, the indices of the first matches are also often wild numbers, built from 0xEEEEEEEE/0xABABABAB/0xCDCDCDCD, which seem to indicate they point to some wrong heap areas.

I include a snapshot of the compact returned values from VS 2012 and the test code I used, still before meaningful code has been run.

Hope someone can explain this, point to something wrong I did, or is that a real bug? Any workaround in this case?

I was also suspecting a possible incompatibility between STL versions between my build and the OpenCV library, but I didn't see such issues when searching.

This happens with 2.4.6

--- Returned values ---
-       matches { size=128 }    ::vector<std::vector<cv::DMatch,std::allocator<cv::DMatch> >,std::allocator<std::vector<cv::DMatch,std::allocator<cv::DMatch> > > >
        [size]  128 __int64
        [capacity]  128 __int64
+       [0] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [1] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [2] { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [3] { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [4] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [5] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [6] { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [7] { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [8] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [9] { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [10]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [11]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [12]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [13]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [14]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [15]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [16]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [17]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [18]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [19]    { size=8 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [20]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [21]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [22]    { size=7 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [23]    { size=8521267 }    std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [24]    { size=0 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
+       [25]    { size=1 }  std::vector<cv::DMatch,std::allocator<cv::DMatch> >
...
 
--- Test Function (based on sample code) ---

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/nonfree/nonfree.hpp"
using namespace cv;

int TestKeypointMatching(const std::string & fname1, const std::string & fname2)
{
    Mat img1 = imread(fname1, CV_LOAD_IMAGE_GRAYSCALE);
    Mat img2 = imread(fname2, CV_LOAD_IMAGE_GRAYSCALE);
    if(img1.empty() || img2.empty())
    {
        printf("Can't read one of the images\n");
        return -1;
    }

    // detecting keypoints
    // Ptr<featuredetector> detector0 = FeatureDetector::create("SurfFeatureDetector");
    SurfFeatureDetector detector(400);
    vector<keypoint> keypoints1, keypoints2;
    detector.detect(img1, keypoints1);
    detector.detect(img2, keypoints2);

    // computing descriptors

    int descVer = 2;
    Feature2D *pExtractor = NULL;

    if (descVer == 1) {  // SURF.
        // SurfDescriptorExtractor extractor;
        pExtractor = new SurfDescriptorExtractor();
    } else if (descVer == 2) {  // SIFT.
        pExtractor = new  SIFT(500, 3, 0.03, 10.0, 1.0);
    }

    Mat descriptors1, descriptors2;
    pExtractor->compute(img1, keypoints1, descriptors1);
    pExtractor->compute(img2, keypoints2, descriptors2);
    // delete pExtractor;  NOTE: this prompts heap corruption exception ?!


    // matching descriptors
    DescriptorMatcher *pMatcher = NULL;
    vector<dmatch> matches;

    int matcherVer = 2;  // Note: error happens for both 1 and 2.

    // BFMatcher matcher;
    if (matcherVer == 1) {  // BFMatcher (Brute Force).
        // SurfDescriptorExtractor extractor;
        pMatcher = new BFMatcher();
    } else if (descVer == 2) {  // BFMatcher (Brute Force) unique cross-check knnMatch.
        pMatcher = new BFMatcher(NORM_L2, true);
    }

    int matchType = 2;  // Note: plain match (1) works fine.
    if (matchType == 1) {  // Plain match().
        pMatcher->match(descriptors1, descriptors2, matches);

        // drawing the results
        namedWindow("matches", 1);
        Mat img_matches;
        drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
        imshow("matches", img_matches);
        waitKey(0);
    } else if (matchType == 2) {  // knnMatch().
        std::vector<std::vector<dmatch> > matches;
        pMatcher->knnMatch(descriptors1, descriptors2, matches, 1);

        Mat img_matches;
        drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
        imshow("matches", img_matches);
        waitKey(0);
    }
}