OpenCV 2.2 SURF Feature matching problems
我已修改 OpenCV 演示应用程序"matching_to_many_images.cpp",以从网络摄像头(右)查询图像(左)到帧。第一张图片的右上角出了什么问题?
我们认为这与我们遇到的另一个问题有关。我们从一个空数据库开始,我们只添加唯一的(与我们数据库中的特征不匹配的特征)但是在只添加三个特征之后,我们得到了所有新特征的匹配......
我们正在使用:
SurfFeatureDetector surfFeatureDetector(400,3,4);
SurfDescriptorExtractor surfDescriptorExtractor;
FlannBasedMatcher flannDescriptorMatcher;
完整代码可在以下网址找到:http://www.copypastecode.com/71973/
我认为这与边界关键点有关。检测器检测关键点,但要使 SURF 描述符返回一致的值,它需要周围像素块中的像素数据,这在边界像素中不可用。您可以使用以下代码段在检测到关键点之后但在计算描述符之前删除边界点。我建议使用 20 或更多的borderSize。
1 2 3 4 5 6 7 8 9 10 11 | removeBorderKeypoints( vector<cv::KeyPoint>& keypoints, const cv::Size imageSize, const boost::int32_t borderSize ) { if( borderSize > 0) { keypoints.erase( remove_if(keypoints.begin(), keypoints.end(), RoiPredicatePic((float)borderSize, (float)borderSize, (float)(imageSize.width - borderSize), (float)(imageSize.height - borderSize))), keypoints.end() ); } } |
其中 RoiPredicatePic 实现为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | struct RoiPredicatePic { RoiPredicatePic(float _minX, float _minY, float _maxX, float _maxY) : minX(_minX), minY(_minY), maxX(_maxX), maxY(_maxY) {} bool operator()( const cv::KeyPoint& keyPt) const { cv::Point2f pt = keyPt.pt; return (pt.x < minX) || (pt.x >= maxX) || (pt.y < minY) || (pt.y >= maxY); } float minX, minY, maxX, maxY; }; |
此外,近似最近邻索引并不是匹配图像对之间特征的最佳方式。我建议您尝试其他更简单的匹配器。
您的方法完美无缺,但由于不正确地调用 drawMatches 函数而显示错误结果。
你的错误调用是这样的:
1 | drawMatches(image2, image2Keypoints, image1, image1Keypoints, matches, result); |
正确的调用应该是:
1 | drawMatches(image1, image1Keypoints, image2, image2Keypoints, matches, result); |
我遇到了同样的问题。令人惊讶的是,该解决方案与边界点或 KNN 匹配器无关。只需要一种不同的匹配策略来从过多的匹配项中过滤掉"好的匹配项"。
使用 2 NN 搜索,以及以下条件 -
如果距离(第一次匹配)< 0.6*距离(第二次匹配)第一次匹配是"好匹配"。
过滤掉所有不满足上述条件的匹配,只为"好匹配"调用drawMatches。瞧!