# Revision history [back]

There are some common methods for filering keypont matches for any descriptor calculating method.

Simple filters, for example Ratio test (See Lowe paper about SIFT), cross-check matching, ...

Ratio: "Therefore, for each feature point, we have two candidate matches in the other view. These are the two best ones based on the distance between their descriptors. If this measured distance is very low for the best match, and much larger for the second best match, we can safely accept the first match as a good one since it is unambiguously the best choice. Reciprocally, if the two best matches are relatively close in distance, then there exists a possibility that we make an error if we select one or the other. In this case, we should reject both matches."

Cross-check:

BruteForceMatcher<L2<float> > descriptorMatcher;
vector<DMatch> filteredMatches12, matches12, matches21;
descriptorMatcher.match( descriptors1, descriptors2, matches12 );
descriptorMatcher.match( descriptors2, descriptors1, matches21 );
for( size_t i = 0; i < matches12.size(); i++ )
{
DMatch forward = matches12[i];
DMatch backward = matches21[forward.trainIdx];
if( backward.trainIdx == forward.queryIdx )
filteredMatches12.push_back( forward );
}


Also you can use geometry validation. For example, if I consider matches between image of a planar object and some scene, I know that there is a homograhy between two images of a planar object. So I can try to find homography with RANSAC scheme and filter matches using this homography.

There are some common methods for filering keypont matches for any descriptor calculating method.

Simple filters, for example Ratio test (See Lowe paper about SIFT), cross-check matching, ...

Ratio: "Therefore, for each feature point, we have two candidate matches in the other view. These are the two best ones based on the distance between their descriptors. If this measured distance is very low for the best match, and much larger for the second best match, we can safely accept the first match as a good one since it is unambiguously the best choice. Reciprocally, if the two best matches are relatively close in distance, then there exists a possibility that we make an error if we select one or the other. In this case, we should reject both matches."

Cross-check:

BruteForceMatcher<L2<float> > descriptorMatcher;
vector<DMatch> filteredMatches12, matches12, matches21;
descriptorMatcher.match( descriptors1, descriptors2, matches12 );
descriptorMatcher.match( descriptors2, descriptors1, matches21 );
for( size_t i = 0; i < matches12.size(); i++ )
{
DMatch forward = matches12[i];
DMatch backward = matches21[forward.trainIdx];
if( backward.trainIdx == forward.queryIdx )
filteredMatches12.push_back( forward );
}


Also you can use geometry validation. validation. For example, if I consider matches between image of a planar object and some scene, I know that there is a homograhy between two images of a planar object. So I can try to find homography with RANSAC scheme and filter matches using this homography.

There are some common methods for filering keypont matches for any descriptor calculating method.

Simple filters, for example Ratio test (See Lowe paper about SIFT), cross-check matching, ...

Ratio: "Therefore, for each feature point, we have two candidate matches in the other view. These are the two best ones based on the distance between their descriptors. If this measured distance is very low for the best match, and much larger for the second best match, we can safely accept the first match as a good one since it is unambiguously the best choice. Reciprocally, if the two best matches are relatively close in distance, then there exists a possibility that we make an error if we select one or the other. In this case, we should reject both matches."

Cross-check:

BruteForceMatcher<L2<float> > descriptorMatcher;
vector<DMatch> filteredMatches12, matches12, matches21;
descriptorMatcher.match( descriptors1, descriptors2, matches12 );
descriptorMatcher.match( descriptors2, descriptors1, matches21 );
for( size_t i = 0; i < matches12.size(); i++ )
{
DMatch forward = matches12[i];
DMatch backward = matches21[forward.trainIdx];
if( backward.trainIdx == forward.queryIdx )
filteredMatches12.push_back( forward );
}


Also you can use geometry validation. For example, if I you consider matches between image of a planar object and some scene, I you know that there is a homograhy between two images of a planar object. So I you can try to find homography with RANSAC scheme and filter matches using this homography.