1 | initial version |
To answer this question more completely, it is worth mentionning that FREAK is a local binary descriptor, that is to say it represents the surrounding of a keypoint in the form of the results of binary tests on the neighboring pixels of the keypoint. In the case of FREAK, the tests are chosen to mimic the behavior of a human retina (see the original paper for more info).
The result of the feature extraction is a u8 matrix with 64 columns because the FREAK descriptor uses 512 binary tests (64*8).
Now, binary descriptors are compared using the Hamming distance, which measures the number of bits with different values between two binary strings. For instance, computing the Hamming distance between "01110101" and "1111011" yields 2. Hence, the possible distance range when comparing two 512-bits strings is between 0 (the two strings are identical) and 512 (the strings are the exact opposites of one another).
To filter out "bad" matches, a distance threshold can be applied : if the Hamming distance between the query point and its nearest neighbor is more than a certain value (say 128, for a FREAK descriptor), then discard it.
Another solution is to perform crosscheck : matchings are done from query descriptors to train descriptors and the other way around. Then, only matches that are found in both directions are kept. To use crosscheck, just set the crosscheck argument of the matching function to true (see documentation).
Lastly, as suggested in the other answer, you can use the 2-nn matching method : instead of looking for the nearest neighbor for each keypoints, take the two nearest neighbors and compare their distances to the query keypoint. If they are not different enough (for instance if distance(query, 2nd best) > 0.8 distance(query, best) ), discard the keypoint. This allows to discard abiguous matches (when two possible matches are too similar to each other).
It is possible to use any combination of these three criteria.
Below is a code example for OpenCV 3.4.1+ :
Mat descriptors1;