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秒。
答案 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对于比较来说会很有趣。