Manually make a pair match in OpenCV from the key points of the function

Here is my problem. I manually extracted key point functions using SURF on multiple images. But I already know which pair of glasses will fit. The fact is that I am trying to create the appropriate pairs, but I do not understand how to do this. I tried to take a look at the code, but this is a mess.

Now I know that the size of the .descriptors, matrix, functions matches the number of key points (another dimension is 1). In the code, it uses only descriptors to determine match pairs, so it compares rows (or columns, I'm not sure) or two descriptor matrices and determines if there is something in common.

But in my case, I already know that there is a match between the key point i from image 1 and the key point j from image 2. How to describe this as the value of MatchesInfo. In particular, matches of elements of type std :: vector <cv :: DMatch>.

EDIT: So, for this I do not need to use any helper or anything like that. I know what couples get together!

+7
source share
1 answer

If I understand that you are asking the right question, I assume that you want the key match to be in std::vector<cv::DMatch> for the purpose of drawing them using OpenCV cv::drawMatches or using with some similar OpenCV function . Since I also performed manual matching recently, here is my code that draws arbitrary matches originally contained in std::vector<std::pair <int, int> > aMatches and displays them in a window:

 const cv::Mat& pic1 = img_1_var; const cv::Mat& pic2 = img_2_var; const std::vector <cv::KeyPoint> &feats1 = img_1_feats; const std::vector <cv::KeyPoint> &feats2 = img_2_feats; // you of course can work directly with original objects // but for drawing you only need const references to // images & their corresponding extracted feats std::vector <std::pair <int, int> > aMatches; // fill aMatches manually - one entry is a pair consisting of // (index_in_img_1_feats, index_in_img_2_feats) // the next code draws the matches: std::vector <cv::DMatch> matches; matches.reserve((int)aMatches.size()); for (int i=0; i < (int)aMatches.size(); ++i) matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second, std::numeric_limits<float>::max())); cv::Mat output; cv::drawMatches(pic1, feats1, pic2, feats2, matches, output); cv::namedWindow("Match", 0); cv::setWindowProperty("Match", CV_WINDOW_FULLSCREEN, 1); cv::imshow("Match", output); cv::waitKey(); cv::destroyWindow("Match"); 

Alternatively, if you need more complete match information for goals more complex than drawing, you can also set the distance between matches to the correct value. For example. if you want to calculate distances using distance L2, you should replace the following line:

 for (int i=0; i < (int)aMatches.size(); ++i) matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second, std::numeric_limits<float>::max())); 

with this (note, this also needs a link to function descriptor vectors):

 cv::L2<float> cmp; const std::vector <std::vector <float> > &desc1 = img_1_feats_descriptors; const std::vector <std::vector <float> > &desc2 = img_2_feats_descriptors; for (int i=0; i < (int)aMatches.size(); ++i){ float *firstFeat = &desc1[aMatches[i].first]; float *secondFeat = &desc2[aMatches[i].second]; float distance = cmp(firstFeat, secondFeat, firstFeat->size()); matches.push_back(cv::DMatch(aMatches[i].first, aMatches[i].second, distance)); } 

Note that in the last fragment descX[i] is a descriptor for featsX[i] , each element of the internal vector is one of the components of the descriptor vector. Also note that all descriptor vectors must have the same dimension.

+5
source

All Articles