您好我正在开发识别模式的Android应用程序,它正如您所见,但我必须面对过度匹配的问题。我已经读过它是因为我的匹配器过于敏感而造成的。为了匹配我使用这种匹配器:
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
...
matcher.match(descriptor1, descriptorLogo, matches);
我也尝试实现knnmatch()
,但是我无法使用函数Features2d.drawMatches()
感谢您的回答,希望它能解决我的问题
答案 0 :(得分:5)
有几种技术可以删除异常值或改进匹配:
交叉检查
比率测试
RANSAC +平面形状的同形
我通常会应用最后两个。
比率测试:
BFMatchermatcher(CV_L2);
vector<vector<DMatch>>nearest_neighbors;
matcher.radiusMatch(
right_points_to_find_flat,
right_features_flat,
nearest_neighbors,
2.0f);
// Check that the found neighbors are unique (throw away neighbors
// that are too close together, as they may be confusing)
std::set<int>found_in_right_points; // for duplicate prevention
for(inti=0;i<nearest_neighbors.size();i++) {
DMatch _m;
if(nearest_neighbors[i].size()==1) {
_m = nearest_neighbors[i][0]; // only one neighbor
} else if(nearest_neighbors[i].size()>1) {
// 2 neighbors – check how close they are
double ratio = nearest_neighbors[i][0].distance / nearest_neighbors[i][1].distance;
if(ratio < 0.7) { // not too close
// take the closest (first) one
_m = nearest_neighbors[i][0];
} else { // too close – we cannot tell which is better
continue; // did not pass ratio test – throw away
}
} else {
continue; // no neighbors... :(
}
RANSAC +单应:
std::vector<Point2f> object;
std::vector<Point2f> scene;
for( int i = 0; i < good_matches.size(); i++ )
{
//-- Get the keypoints from the good matches
object.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );
scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
}
Mat H = findHomography( object, scene, CV_RANSAC, status );
//draw only the matches considered inliers by RANSAC => status=1
for(i=0;i=object.size();i++){
if(status[i])
{
}
}
答案 1 :(得分:3)
首先,在匹配向量中,每个匹配都有一个置信度量。您只能选择信心十足的人。
第二种方法,即通过调整关键点提取算法,可以提供更好的性能提升。阅读您选择的描述符,并查看输入参数如何影响所选点的数量。在构造函数中设置这些参数。你必须经常测试它,并检查最终结果的质量是否会降低。