有一个匹配两个图像并输出旋转和缩放的 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 秒。