2011-05-30 79 views
6

Matching with nothing in the top right corner的OpenCV 2.2 SURF特征匹配问题

我已经修改OpenCV的演示应用程序“matching_to_many_images.cpp”从网络摄像头(右)查询图像(左)至一个帧。第一张图片右上角出了什么问题?

我们认为这与我们的另一个问题有关。我们从一个空的数据库开始,我们只添加独特的(与我们的数据库中的功能不匹配的功能),但添加三个功能后,我们得到所有新功能的匹配... ...

我们正在使用: SurfFeatureDetector surfFeatureDetector(400,3,4); SurfDescriptorExtractor surfDescriptorExtractor; FlannBasedMatcher flannDescriptorMatcher; http://www.copypastecode.com/71973/

+0

要100%正确,它是右图像的左上角。我们需要一种方式来筛选这些明显错误的匹配,任何想法?为什么这些点被检测为匹配? – Orka 2011-05-30 09:37:45

+0

您应该将我的答案标记为正确答案。实际的一个是误导。 – 2013-05-12 12:28:34

回答

10

我觉得这与边框的关键点做:

完整代码可以在这里找到。检测器检测关键点,但是对于SURF描述符返回一致的值,它需要围绕它的像素块中的像素数据,这在边界像素中不可用。在检测到关键点之后但计算描述符之前,可以使用以下片段删除边界点。我建议使用20或更多的borderSize。

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实现为:

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; 
}; 

此外,近似最近邻索引是不匹配的图像对之间的功能的最佳途径。我建议你尝试其他更简单的匹配器。

+0

整洁,好点!在我们的“生产”代码中,我们转而使用强力匹配器来代替。我将以您的代码片段为指导,研究这些要点。 – Orka 2011-05-31 06:15:08

+0

这解决了我们以前遇到的问题,并回答了问题。可悲的是,这不是我们的数据库匹配问题的原因..回到调试! 感谢您的回答! – Maidenone 2011-05-31 10:00:07

4

您的方法工作完美无瑕,但由于错误地调用drawMatches函数而显示错误结果。

你不正确的呼叫是这样的:

drawMatches(image2, image2Keypoints, image1, image1Keypoints, matches, result); 

正确的调用应该是:

drawMatches(image1, image1Keypoints, image2, image2Keypoints, matches, result); 
3

我面临同样的问题。令人惊讶的是,该解决方案与边界点或KNN匹配器无关。只需要一个不同的匹配策略来筛选出过多比赛中的“优秀比赛”。

使用2 NN搜索,并且以下条件 -

如果距离(1匹配)< 0.6 *距离(第二节比赛)第一次比赛是“门当户对”。

过滤出所有不符合上述条件的匹配项,并仅为“匹配项”调用drawMatches。瞧!