SURF(Speeded Up Robust Feature),加速稳健特征检测,是一种对图像角点、边缘特征提取的一种算法。SURF在SIFT算法的基础上做了很多改进,不但求解速度更快,而且鲁棒性更强。
一、SURF算法特点
1、简单——SURF通过利用Haar小波在不同尺度空间和不同方向上快速计算Hessian矩阵的行列式,避免了SIFT中高斯金字塔计算时的大量耗时。
//创建SURF特征检测器
Ptr featureDetector = SURF::create(800, 4, 3, true, false);
//定义vector保存检测到的特征点
vector keypoints;
//检测特征点
featureDetector->detect(image, keypoints);
2、有效——SURF特征描述子使用一个128维向量表示局部矩形区域内的特征,该向量中前64维用于表示该区域的平均强度,后64维则表示梯度方向直方图,该方法可以有效地区分不同区域的特征点。
//创建SURF特征检测并提取器
Ptr detector = SURF::create(800, 4, 3, true, false);
Ptr extractor = SURF::create();
//定义vector保存提取到的特征描述子
vector keypoints;
Mat descriptors;
//检测特征点和提取特征描述子
detector->detectAndCompute(image, Mat(), keypoints, descriptors);
3、适应性——SURF可以在旋转、缩放、仿射和光照变化时提取出相同的特征点描述子,这大大增加了特征检测的鲁棒性。
二、SURFFeatureDetector算法源码解析
SURF特征检测器的主要工作流程是在多尺度空间高斯差分图像中搜索极值点,然后通过对极值点周围的像素求解Hessian矩阵的行列式,进一步抑制边缘响应,提取出稳定的角点特征和边缘特征。
void SURFFeatureDetector::detectImpl(InputArray _image, OutputArray _keypoints, InputArray _mask)
{
...
//对多尺度高斯差分图像进行极值点检测
for (size_t octave = 0; octave < nOctaves; octave++)
{
...
for (int layer = 1; layer < nLayers - 2; layer++)
{
...
for (int r = 0; r < img_rows; ++r)
{
...
for (int c = 0; c < img_cols; ++c)
{
...
//检测极值点
if (isExtremum(layer, r, c, threshold))
{
...
//求解极值点的关键属性
if (getPointOctave(keypoint.pt, response_layer,
(int)m_nOctaveLayers,
(float)m_contrastThreshold,
(float)m_edgeThreshold) == octave)
{
...
//添加检测到的关键点
keypoints.push_back(keypoint);
}
}
}
}
}
}
//对响应强度进行排序
...
}
三、SURFFeatureDetector算法参数分析
1、nOctaves——高斯金字塔的层数
nOctaves决定了不同尺度上的高斯平滑程度以及对比度范围,通常取5或6为宜。
Ptr detector = SURF::create(800, 5, 3, true, false);
2、nOctaveLayers——每组高斯金字塔的层数
nOctaveLayers决定了每组高斯金字塔上的尺度数目,通常取2或3为宜。
Ptr detector = SURF::create(800, 4, 3, true, false);
3、contrastThreshold——用于筛选极值点的响应阈值
contrastThreshold表示相邻两个尺度高斯差分图像之间的比值阈值,小于该比值则会被滤除。
Ptr detector = SURF::create(800, 4, 3, true, false);
detector->setContrastThreshold(0.03f);
4、edgeThreshold——抑制边缘响应的阈值
edgeThreshold表示边缘响应阈值,用来抑制边缘响应的干扰。
Ptr detector = SURF::create(800, 4, 3, true, false);
detector->setEdgeThreshold(10);
5、upright——方向不变性
upright为true表示SURF特征检测器不计算特征点的方向,可以提高匹配速度,但丢失了旋转不变性;为false表示计算特征点方向。
Ptr detector = SURF::create(800, 4, 3, false, false);
四、SURFFeatureDetector实例应用——特征匹配
SURF特征检测器除了可以用于特征提取,还可以用于特征匹配,下面简要介绍一下SURF特征点匹配的一般流程。
1、使用SURF特征检测器对两张待匹配图像提取特征点和特征描述子。
Ptr detector = SURF::create(800, 4, 3, true, false);
Ptr extractor = SURF::create();
vector keypoints1, keypoints2;
Mat descriptors1, descriptors2;
detector->detectAndCompute(image1, Mat(), keypoints1, descriptors1);
detector->detectAndCompute(image2, Mat(), keypoints2, descriptors2);
2、使用FlannBasedMatcher或BruteForceMatcher对两幅图像的特征描述子进行匹配。
BFMatcher matcher(NORM_L2, true);
vector> matchePoints;
//knn匹配,默认k=2
matcher.knnMatch(descriptors1, descriptors2, matchePoints, 2);
3、根据匹配点对的阈值把匹配点分为多个类别,并进行筛选,删除错误匹配。
vector goodMatches;
for (const auto& match : matchePoints)
{
if (match[0].distance < 0.75f * match[1].distance)
{
goodMatches.push_back(match[0]);
}
}
4、使用findHomography或RANSAC算法进行图像配准。
vector imagePoints1, imagePoints2;
for (const auto& match : goodMatches)
{
imagePoints1.push_back(keypoints1[match.queryIdx].pt);
imagePoints2.push_back(keypoints2[match.trainIdx].pt);
}
Mat H = findHomography(imagePoints1, imagePoints2, RANSAC);
至此,SURF特征点匹配的整个流程就完成了,可以将匹配结果进行可视化处理。
五、总结
本文介绍了图像特征检测器中的4.7.0 SURFFeatureDetector算法,该算法具有简单、有效、适应性等特点,可以用于提取图像中的角点、边缘特征。同时,本文还对SURFFeatureDetector算法源码进行了解析,介绍了算法的主要工作流程和参数分析。最后,本文还通过特征匹配的实例应用,演示了SURF特征点匹配的整个流程,相信读者对图像特征检测器有了更深入的认识,希望读者能够将该算法运用到实际的图像处理领域当中。
本文链接:https://my.lmcjl.com/post/5920.html
4 评论