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