使用SURF匹配旋转图像的特征点

信息处理 计算机视觉
2022-02-14 10:41:12

我正在尝试使用带有 opencv 的 SURF 来匹配 2 个图像之间的 SURF 点。一个是另一个的旋转。问题是它可以找到的少数匹配是错误的。

匹配点的图像

我主要从 opencv http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html#feature-flann-matcher 获取我的代码

这是代码:

string imageName1="test_right_rotate.jpg";
string imageName2="test_right.jpg";
Mat image1 = imread( imageName1, 1 );
Mat image2 = imread( imageName2, 1 );
int minHessian = 500;
SurfFeatureDetector detector( minHessian );
std::vector<KeyPoint> keypoints_1, keypoints_2;

detector->detect( image1, keypoints_1 );
detector->detect( image2, keypoints_2 );

SurfDescriptorExtractor extractor;
Mat descriptors_1, descriptors_2;

extractor.compute( image1, keypoints_1, descriptors_1 );
extractor.compute( image2, keypoints_2, descriptors_2 );

FlannBasedMatcher matcher;
std::vector<vector<DMatch > > matches;
matcher.knnMatch(descriptors_1,descriptors_2, matches, 2);
std::vector< DMatch > good_matches;
for(int i = 0; i < min(descriptors_1.rows-1,(int) matches.size()); i++) //THIS LOOP IS SENSITIVE TO SEGFAULTS
{
    if((matches[i][0].distance < 0.6*(matches[i][1].distance)) && ((int) matches[i].size()<=2 && (int) matches[i].size()>0))
    {
        good_matches.push_back(matches[i][0]);
    }
}
Mat img_matches;
drawMatches( image1, keypoints_1, image2, keypoints_2, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

它适用于缩放图像和翻译图像,但不适用于旋转图像。

编辑:

我不知道出了什么问题,但我没有使用 SURF,而是使用 ORB 作为检测器,使用 FREAK 作为提取器,它的效果要好得多。您可以在此 SO 上找到代码:https ://stackoverflow.com/questions/12491022/opencv-freak-fast-retina-keypoint-descriptor

1个回答

SURF 特征并非完全旋转不变。

论文中,他们尝试通过遵循以下方法使 SURF 对旋转更加鲁棒。

为了提高旋转的性能,描述符是基于多方向的。多对多暂定对应关系由最大距离确定。霍夫变换用于拒绝不匹配,并用最小二乘解计算仿射参数。

图像匹配算法在图像旋转方面表现出比标准 SURF 更好的性能,并且它成功地匹配了包含重复图案的图像,这会降低特征描述符的独特性。