What to do with DMatch value ?
I have this code for image matching using ORB
FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);;
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
File root = Environment.getExternalStorageDirectory();
File file = new File( root, "nano1.jpg");
File file2 = new File( root, "nano2.jpg");
Log.d(LOG_TAG, "File " + file.exists() + " & "+ file2.exists() + " " + root.getAbsolutePath());
//first image
Mat img1 = Highgui.imread(file.getAbsolutePath());
Mat descriptors1 = new Mat();
MatOfKeyPoint keypoints1 = new MatOfKeyPoint();
detector.detect(img1, keypoints1);
descriptor.compute(img1, keypoints1, descriptors1);
//second image
Mat img2 = Highgui.imread(file2.getAbsolutePath());
Mat descriptors2 = new Mat();
MatOfKeyPoint keypoints2 = new MatOfKeyPoint();
detector.detect(img2, keypoints2);
descriptor.compute(img2, keypoints2, descriptors2);
//matcher should include 2 different image's descriptors
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1,descriptors2,matches);
Log.d(LOG_TAG, "size " + matches.size());
//feature and connection colors
Scalar RED = new Scalar(255,0,0);
Scalar GREEN = new Scalar(0,255,0);
//output image
Mat outputImg = new Mat();
MatOfByte drawnMatches = new MatOfByte();
//this will draw all matches, works fine
Features2d.drawMatches(img1, keypoints1, img2, keypoints2, matches,
outputImg, GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);
int DIST_LIMIT = 80;
List<DMatch> matchList = matches.toList();
List<DMatch> matches_final = new ArrayList<DMatch>();
for(int i=0; i<matchList.size(); i++){
if(matchList.get(i).distance <= DIST_LIMIT){
matches_final.add(matches.toList().get(i));
}
}
MatOfDMatch matches_final_mat = new MatOfDMatch();
matches_final_mat.fromList(matches_final);
for(int i=0; i< matches_final.size(); i++){
Log.d(LOG_TAG,""+ matches_final.get(i));
}
And in the matches I get
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=0, trainIdx=8, imgIdx=0, distance=63.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=1, trainIdx=81, imgIdx=0, distance=78.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=2, trainIdx=162, imgIdx=0, distance=73.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=3, trainIdx=189, imgIdx=0, distance=75.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=4, trainIdx=88, imgIdx=0, distance=77.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=5, trainIdx=89, imgIdx=0, distance=60.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=6, trainIdx=81, imgIdx=0, distance=78.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=7, trainIdx=68, imgIdx=0, distance=57.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=8, trainIdx=298, imgIdx=0, distance=48.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=9, trainIdx=12, imgIdx=0, distance=39.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=10, trainIdx=479, imgIdx=0, distance=66.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=11, trainIdx=480, imgIdx=0, distance=63.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=12, trainIdx=125, imgIdx=0, distance=56.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=13, trainIdx=298, imgIdx=0, distance=71.0]
08-08 14:59:29.569: D/FdActivity(9001): DMatch [queryIdx=14 ...
Discard some matches based on distance, it seems the only parameter of use in DMatch. Or apply some algorithms like testing symmetry between matches(find matches for image1 in image2 and vice versa, then check if they are symmetrical), or try RANSAC and so on.
@mada Can you give some lead on how to do that ?
@ximobayo explained it quite good. Using knnMatch will give you more options in discarding false matches, also check this out: http://answers.opencv.org/question/11840/false-positive-in-object-detection/