0

有一个匹配两个图像并输出旋转和缩放的 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++ 中的匹配项进行排序,但没有成功。值范围在 300 到 700 之间,即使是距离最短的匹配项也几乎完全不正确。

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

编辑:

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

4

1 回答 1

0

您使用的方法会为每个点找到最近的邻居,无论它有多近。有两种常见的策略: 1. 将集合 A 匹配到集合 B,将 B 匹配到 A,并且只保留两个匹配中都存在的匹配。2. 使用 2 knnMatch 并执行比率检查,即只保留 1 NN 比 2 NN 更接近的匹配,例如 d1 < 0.8 * d2。

MATLAB 代码使用 SURF。OpenCV 还提供了 SURF、SIFT 和 AKAZE,试试这些。特别是 SURF 进行比较会很有趣。

于 2017-04-01T22:05:24.483 回答