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);
}
}