尺度不变特征的检测 - sumpig/OpenCV GitHub Wiki
尺度不变特征的理念是在任何尺度下拍摄的物体都能检测到一致的关键点,而且每个被检测的特征点都对应一个尺度因子。理想情况下,对于两幅图像中不同尺度的同一个物体点,计算得到的两个尺度因子之间的比率应该等于图像尺度的比率。
SURF
SURF 特征检测属于 opencv_contrib 库,在编译OpenCV 时包含了附加模块才能使用。
首先创建检测器实例,然后调用它的检测方法:
// 创建SURF 特征检测器对象
cv::Ptr<cv::xfeatures2d::SurfFeatureDetector> ptrSURF =
cv::xfeatures2d::SurfFeatureDetector::create(2000.0);
// 检测关键点
ptrSURF->detect(image, keypoints);
画出这些特征:
// 画出关键点,包括尺度和方向信息
cv::drawKeypoints(image, // 原始图像
keypoints, // 关键点的向量
featureImage, // 结果图像
cv::Scalar(255, 255, 255), // 点的颜色
cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS 标志以显示相关的尺度因子。
原理
如果在不同的尺度内用高斯滤波器计算指定像素的拉普拉斯算子,会得到不同的数值。观察滤波器对不同尺度因子的响应规律,所得曲线最终在给定的σ 值处达到最大值。对于以不同尺度拍摄的两幅图像的同一个物体,对应的两个σ 值的比率等于拍摄两幅图像的尺度的比率。这一重要观察是尺度不变特征提取过程的核心。也就是说,为了检测尺度不变特征,需要在图像空间(图像中)和尺度空间(通过在不同尺度下应用导数滤波器得到)分别计算局部最大值。
SIFT
SIFT 检测特征时也采用了图像空间和尺度空间的局部最大值,但它使用拉普拉斯滤波器响应,而不是Hessian 行列式值。
SIFT 特征的检测过程与SURF 非常相似:
// 构建SIFT 特征检测器实例
cv::Ptr<cv::xfeatures2d::SiftFeatureDetector> ptrSIFT =
cv::xfeatures2d::SiftFeatureDetector::create();
// 检测关键点
ptrSIFT->detect(image, keypoints);
由于SIFT 基于浮点内核计算特征点,因此通常认为SIFT 算法检测在空间和尺度上能取得更加精确的定位。基于同样的原因,它的计算效率也更低,尽管相对效率取决于具体的实现方法。