Skip to content
Advertisement

Why and how apply thresholding to get better matched features

in the below code, i am doing descriptor matching using BRUTFORCE algorithm. i read som tutorial but they were writtin in C++, and i found that, always after the matching process, the resultant MatOfDMatch object from

.match(query_desc, train_desc, MatOfDMatch objec)

should be converted to DMatch objectas follows

List<DMatch> dMtchList = matDMatch.toList();

and the dMtchList should be sorted Ascendingly, and then a thresholing should be applied and then convert the dMtchList object to MatOfDMatch.

my question is, why do we need to apply thresholding since i can sort the raw matches returned from the .match(..,..,..) method ascendingly, and how the thresholding enhance the matching.

**code*:

private static void descriptorMatcher() {
    // TODO Auto-generated method stub
    MatOfDMatch matDMatch = new MatOfDMatch();//empty MatOfDmatch object
    dm.match(matFactory.getComputedDescExtMatAt(0), matFactory.getComputedDescExtMatAt(1), matDMatch);//descriptor extractor of the query and the train image are used as parameters 
    matFactory.addRawMatchesMatDMatch(matDMatch);

    /*writing the raw MatDMatches*/
    Mat outImg = new Mat();
    Features2d.drawMatches(matFactory.getMatAt(0), matFactory.getMatKeyPtsAt(0), matFactory.getMatAt(1), matFactory.getMatKeyPtsAt(1), MatFactory.lastAddedObj(matFactory.getRawMatchesMatDMatchList()), 
            outImg);
    matFactory.addRawMatchedImage(outImg);
    MatFactory.writeMat(FilePathUtils.newOutputPath(SystemConstants.RAW_MATCHED_IMAGE), MatFactory.lastAddedObj(matFactory.getRawMatchedImageList()));//this produce img_2 below posted

    /*getting the top 10 shortest distance*/
    List<DMatch> dMtchList = matDMatch.toList();
    List<DMatch> goodDMatchList = MatFactory.getTopGoodMatches(dMtchList, 0, 10);//this method sort the dMatchList ascendingly and picks onlt the top 10 distances and assign these values to goodDMatchList

    /*converting the goo DMatches to MatOfDMatches*/
    MatOfDMatch goodMatDMatches = new MatOfDMatch();
    goodMatDMatches.fromList(goodDMatchList);
    matFactory.addGoodMatchMatDMatch(goodMatDMatches);

    /*drawing the good matches and writing the good matches images*/
    Features2d.drawMatches(matFactory.getMatAt(0), matFactory.getMatKeyPtsAt(0), matFactory.getMatAt(1), matFactory.getMatKeyPtsAt(1), MatFactory.lastAddedObj(matFactory.getGoodMatchMatDMatchList()), 
            outImg);
    MatFactory.writeMat(FilePathUtils.newOutputPath(SystemConstants.GOOD_MATCHED_IMAGE), outImg);// this produce img_1 below posted
}

Advertisement

Answer

Filtering allows you to thin out your matches so only the best remain and gives you some control over deciding what makes a good match it also is what can give weight to your results.

There’s nothing stopping you from just picking the top 10 closest matches, but they don’t really mean anything if they’re not compared to some standard or guidelines.

By limiting yourself to the top N matches you may also be missing out on many more potential matches especially if you have hundreds or thousands of matches returned from extraction.

Lets say you were comparing two images A and B.

You can say there’s a good chance they’re both similar if you receive 1000 matches in total and 900 of them pass your series of threshold/filtering checks. Where if only 50 passed its not likely the two images are similar at all.

However if you just look at the top 10 matches there’s not much you can really determine, they may be the best of many strong matches if the images or similar or the best of many weak matches if the images are very different.

Edit – Distances

The distance is a measure of similarity between two keypoints, the larger the distance the less similarity and the smaller the distance the greater the similarity.

In the example you’re looking at the max and min distances are initialised as follows:

[ http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html ]

double max_dist = 0; double min_dist = 100;

This is just so they can be updated with the actual min/max values present in the match list. If min started as 0 it may never be overwritten and vice versa for max distance.

  for( int i = 0; i < descriptors_1.rows; i++ ){ 
    double dist = matches[i].distance;
    if( dist < min_dist ) min_dist = dist;
    if( dist > max_dist ) max_dist = dist;
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement