从两个图像转换OpenCV

时间:2017-04-01 16:59:32

标签: c++ matlab opencv match keypoint

Theres是一个匹配两个图像并输出旋转和比例的MATLAB示例: https://de.mathworks.com/help/vision/examples/find-image-rotation-and-scale-using-automated-feature-matching.html?requestedDomain=www.mathworks.com

我的目标是使用C ++重新创建此示例。我使用相同的关键点检测方法(Harris),关键点似乎与Matlab发现的大致相同。到现在为止还挺好。

cv::goodFeaturesToTrack(image_grayscale, corners, number_of_keypoints, 0.01, 5, mask, 3, true, 0.04);
    for (int i = 0; i < corners.size(); i++) {
        keypoints.push_back(cv::KeyPoint(corners[i], 5));
    }

BRISK用于从关键点提取特征。

int Threshl = 120;
int Octaves = 8;
float PatternScales = 1.0f;

cv::Ptr<cv::Feature2D> extractor = cv::BRISK::create(Threshl, Octaves, PatternScales);
extractor->compute(image, mykeypoints, descriptors);

然后使用flannbasedmatcher匹配这些描述符。

cv::FlannBasedMatcher matcher;
matcher.match(descriptors32A, descriptors32B, matches);

现在问题是大约80%的比赛都是错误的并且无法使用。对于相同的图像集,Matlab只返回几个匹配,其中只有约20%是错误的。我已经尝试根据它们的距离值对C ++中的Matches进行排序但没有成功。值范围在300到700之间,即使是最低距离的匹配也几乎完全不正确。

现在20%的良好匹配足以计算偏移量,但在检查错误匹配时浪费了大量处理能力。什么是更好的方法来排序正确的比赛或有什么明显我做错了?

编辑:

我已经从Harris / BRISK切换到AKAZE,这似乎提供了更好的功能和匹配,可以很容易地按距离值进行排序。唯一的缺点是更高的计算时间。有两个1000px宽的图像,AKAZE需要半分钟才能找到关键点(在PC上)。我通过缩小图像来减少这一点,这使得可接受的~3-5秒。

1 个答案:

答案 0 :(得分:0)

您正在使用的方法为每个点找到最近的邻居,无论它距离多近。两种策略很常见: 1.匹配集A以设置B并将B设置为A并仅保留两个匹配中存在的匹配。 2.使用2 knnMatch并执行比率检查,即仅保留1 NN比2 NN更接近的匹配,例如, d1&lt; 0.8 * d2。

MATLAB代码使用SURF。 OpenCV还提供SURF,SIFT和AKAZE,尝试其中之一。特别是SURF对于比较来说会很有趣。