Ask Your Question
2

BFMatcher crosscheck

asked 2013-07-31 05:26:15 -0500

Moster gravatar image

updated 2013-07-31 08:37:02 -0500

Hey guys,

Ive got a problem with the crosscheck feature in the BFMatcher. Im trying to use this on android, but somehow the matcher seems to do crap. It produces lots of good results, but sometimes it returns queryIdx' and trainIdx' that are far away from the number of Matches. Basically I declare the matcher to use crosscheck and I also use knnMatch with k=1. After they got matched, I log the indices. Lots of them are correct, but not all.

BFMatcher matcher(NORM_HAMMING,true);
matcher.knnMatch(queryDescriptors, trainDescriptors, matches, 1);

for (unsigned int i=0; i<matches.size(); i++){

        LOGE("query Idx:%d, trainIdx:%d", matches[i][0].queryIdx, matches[i][0].trainIdx);

           /* circle(*frame,queryPoints[matches[i][0].queryIdx].pt, 1, Scalar(255,255,0,255));
            line(*frame,queryPoints[matches[i][0].queryIdx].pt, trainPoints[matches[i][0].trainIdx].pt, Scalar(255,255,255,255));
            circle(*frame,trainPoints[matches[i][0].trainIdx].pt, 1, Scalar(255,0,0,255));*/
    }

edit:

Ok, I solved it on my own. I debugged the code on android and in the end its pretty obvious. The problem is that the matcher creates an entry in std::vector<std::vector<dmatch>> matches, but if the match is invalid, it does not fill this entry. So obviously this entry is empty and if you access it, there is crap in it. So a simple check if that entry is empty solves everything.

for (unsigned int i=0; i<matches.size(); i++){
        if (!matches[i].empty())
        LOGE("query Idx:%d, trainIdx:%d", matches[i][0].queryIdx, matches[i][0].trainIdx);

}
edit retag flag offensive close merge delete

Comments

Some of the log

(13765): query Idx:27, trainIdx:18

(13765): query Idx:1075809540, trainIdx:1075809540

(13765): query Idx:1, trainIdx:1514815912

(13765): query Idx:7, trainIdx:49

(13765): query Idx:31, trainIdx:7

(13765): query Idx:104, trainIdx:18

Moster gravatar imageMoster ( 2013-07-31 05:26:43 -0500 )edit

When I run your code at first I've got this error: error: ‘struct cv::DMatch’ has no member named ‘empty’ but then I've noticed you wrote that you use std::vector<std::vector<dmatch>> matches

So from what you wrote here, you have a set of matches that you check only the first match!! (match[i][0]) that why you never go deep to the knn garbage I've solved it by looking at the distance as I wrote in my answer.

Eran gravatar imageEran ( 2014-02-04 02:53:50 -0500 )edit

1 answer

Sort by » oldest newest most voted
0

answered 2014-02-04 02:52:25 -0500

Eran gravatar image

I've came across with thus issue also. I tried to avoid it but I was needed that cross-check. You can see the matches results:

BFMatcher matcher(NORM_L2):
-- Max dist : 1.656894 
-- Min dist : 0.855967 
0. distance: 0.906053, imgIdx: 0, queryIdx: 0, trainIdx: 14
1. distance: 1.11377, imgIdx: 0, queryIdx: 1, trainIdx: 20
2. distance: 0.998074, imgIdx: 0, queryIdx: 2, trainIdx: 14
3. distance: 1.65689, imgIdx: 0, queryIdx: 3, trainIdx: 5
4. distance: 1.04289, imgIdx: 0, queryIdx: 4, trainIdx: 14
5. distance: 1.45203, imgIdx: 0, queryIdx: 5, trainIdx: 6
6. distance: 1.60162, imgIdx: 0, queryIdx: 6, trainIdx: 6
7. distance: 0.968847, imgIdx: 0, queryIdx: 7, trainIdx: 56
8. distance: 0.900678, imgIdx: 0, queryIdx: 8, trainIdx: 56
9. distance: 0.855967, imgIdx: 0, queryIdx: 9, trainIdx: 88
10. distance: 1.29085, imgIdx: 0, queryIdx: 10, trainIdx: 88
11. distance: 1.49221, imgIdx: 0, queryIdx: 11, trainIdx: 43
12. distance: 1.2633, imgIdx: 0, queryIdx: 12, trainIdx: 103
13. distance: 1.36239, imgIdx: 0, queryIdx: 13, trainIdx: 43
14. distance: 1.54558, imgIdx: 0, queryIdx: 14, trainIdx: 88
15. distance: 0.980541, imgIdx: 0, queryIdx: 15, trainIdx: 103

BFMatcher matcher(NORM_L2,1):
-- Max dist : 0.775846 
-- Min dist : 0.000000 
0. distance: 0.191887, imgIdx: 0, queryIdx: 0, trainIdx: 14
1. distance: 0.236683, imgIdx: 0, queryIdx: 1, trainIdx: 20
2. distance: 0.775846, imgIdx: 0, queryIdx: 2, trainIdx: 150
3. distance: 0.58364, imgIdx: 0, queryIdx: 3, trainIdx: 119
4. distance: 0.54844, imgIdx: 0, queryIdx: 4, trainIdx: 137
5. distance: 0.375308, imgIdx: 0, queryIdx: 5, trainIdx: 44
6. distance: 0.292175, imgIdx: 0, queryIdx: 6, trainIdx: 6
7. distance: 0.33761, imgIdx: 0, queryIdx: 7, trainIdx: 40
8. distance: 0.217681, imgIdx: 0, queryIdx: 8, trainIdx: 56
9. distance: 0.173051, imgIdx: 0, queryIdx: 9, trainIdx: 88
10. distance: 0.317514, imgIdx: 0, queryIdx: 10, trainIdx: 97
11. distance: 0.526101, imgIdx: 0, queryIdx: 12, trainIdx: 107
12. distance: 0.394886, imgIdx: 0, queryIdx: 13, trainIdx: 43
13. distance: 0.444844, imgIdx: 0, queryIdx: 14, trainIdx: 17
14. distance: 0.210094, imgIdx: 0, queryIdx: 15, trainIdx: 103
15. distance: 1.96182e-44, imgIdx: 0, queryIdx: 1063263759, trainIdx: 265

(which give me the next error when it try to draw matches: OpenCV Error: Assertion failed (i1 >= 0 && i1 < static_cast<int>(keypoints1.size())) in drawMatches, file /home/eran/opencv-2.4.6.1/modules/features2d/src/draw.cpp, line 207)

I've solved it by removing it from my good_matches

  • imgIdx - sometimes wrong sometimes ok
  • queryIdx & trainIdx - most of times garbaged only in one side
  • distance - always somwething very small. in this case: 1.96182e-44

I added this code to min-max loop and the good_matches loop:

if (matches[i].distance < 0.00001) continue;

I hope that this number 0.00001 will catch all cases.

Or someone will fix this knn match bug :~

edit flag offensive delete link more

Comments

Your solution seems to be unreliable. If you use crosscheck, you need knnMatch with exactly 1 match. So of course I only check the first match, since there is only 1 match. In case it does not find any match, the entry will be created, but not filled. So the check matches[i].empty works totally fine. Obviously matches is of the type vector<vector<DMatch>>. This is what knnMatch requires.

Moster gravatar imageMoster ( 2014-02-05 01:19:11 -0500 )edit

Question Tools

Stats

Asked: 2013-07-31 05:26:15 -0500

Seen: 2,588 times

Last updated: Feb 04 '14