sift程序详解
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
调整局部极值函数 函数功能:精确定位关键点位置和尺度并进行插值处理,去除边缘不稳定的点 static bool adjustLocalExtrema( const std::vector<Mat>& dog_pyr, KeyPoint& kpt, int octv,int& layer, int& r, int& c, int nOctaveLayers, float contrastThreshold, float edgeThreshold, float sigma ) 入口参数: 参数const std::vector<Mat>& dog_pyr:DOG尺度空间金字塔 参数KeyPoint& kpt:定义了一个KeyPoint类对象用来存放筛选通过的关键点 参数int octv:该像素点所在的组数 参数int& layer:该像素点所在的层数 参数int& r:该像素点所在的行 参数int& c:该像素点所在的列 参数int nOctaveLayers:金字塔每组的层数S 参数float contrastThreshold:对比度阈值0.04 参数float edgeThreshold:边缘响应阈值 参数float sigma:此处的sigma为初始尺度sigma0 返回值:若极值调整成功返回1,调整失败返回0
图像尺度空间的构建 1.2构建图像金字塔函数: 函数功能:将输入图像作为金字塔初始图像,通过不断进行高斯模糊和降采样后的 图片存放在Mat类容器中 c++:void SIFT_Impl::buildGaussianPyramid( const Mat& base, std::vector<Mat>& pyr, int nOctaves ) const 入口参数: ①参数const Mat& base:输入图像 ②参数std::vector<Mat>& pyr:用于存储金字塔图像的容器 ③参数int nOctaves:金字塔的组数 返回值:无
说明:一个图像的尺度空间L(x,y, σ),定义为原始图像I(x,y)与一个可变尺度的2维高斯函数
G(x,y, σ)卷积产生: 其中: lowe 把初始图像的尺度I(x,y) 设置为0.5即:I(x,y) = I(x,y,0.5),那么由L(x,y, σ1)得到L(x,y, σ2),即 由尺度为σ1的图像生成尺度为σ2的图像的公式为:
计算sift特征描述子 函数功能:去除关键点所在高斯金字塔的层数,组数,以及尺度比例因子 以方便后面计算描述子 unpackOctave(const KeyPoint& kpt, int& octave, int& layer, float& scale) 入口参数: ①参数const KeyPoint& kpt:关键点 ②参数int& octave:关键点所在层 ③参数int& layer:关键点所在组 ④参数float& scale:关键点所在尺度的比例因子 返回值:无
图像尺度空间的构建
1.3构建图像DOG金字塔函数: 函数功能:将构建好的高斯金字塔相邻层相减后构成DOG金字塔存放在Mat类容器中 void SIFT_Impl::buildDoGPyramid( const std::vector<Mat>& gpyr, std::vector<Mat>& dogpyr ) const 入口参数: ①参数:vector<Mat>& gpyr:存放高斯金字塔图片的容器 ②参数:vector<Mat>& dogpyr: 存放DOG金字塔图片的容器 返回值:无
createInitialImage() 图像初始化函数
buildGaussianPy ramid()构建高斯 金字塔函数
buildDoGPyra mid()构建DOG 金字塔函数
findScaleSpaceEx trema()检测尺度空 间极值函数 calcOrientation Hist()计算关键点 主方向函数
SIFT_Impl类
SIFT类
feature2d的子类
Feature2D
父类/基类
PART TWO.运行架构
主函数 int main() { //创建SIFT_Impl类指针 Ptr<Feature2D> f2d = xfeatures2d::SIFT::create(); Mat img_1 = imread("1.jpg");//读入图片 vector<KeyPoint> keypoints_1; //用于存放检测到的关键点的容器 f2d->detect(img_1, keypoints_1);//检测出关键点 Mat descriptors_1; f2d->compute(img_1, keypoints_1, descriptors_1); //计算描述子 waitKey(0); //等待任意按键按下 }
关键点定位 关键点定位并确定主方向函数 函数功能:(1)在DOG空间检测极值点 (2)精确定位关键点位置和尺度并进行插值处理 (3)去除边缘不稳定的点 (4)为关键点分配主方向 void SIFT_Impl::findScaleSpaceExtrema( const std::vector<Mat>& gauss_pyr, const std::vector<Mat>& dog_pyr,std::vector<KeyPoint>& keypoints ) const 入口参数: ①参数const std::vector<Mat>& gauss_pyr:高斯金字塔容器 ②参数const std::vector<Mat>& dog_pyr:DOG金字塔容器 ③参数std::vector<KeyPoint>& keypoints:存放关键点容器 返回值:无
Feature2D::detect(InputArray image, CV_OUT std::vector<KeyPoint>& keypoints, InputArray mask=noArray()) 调用了 检测关键点函数 SIFT_Impl::detectAndCompute(image, mask, keypoints, noArray(), false);
SIFT特征提取过程中 的核心函数
PART ONE.物理架构 opencv_contrib-3.1.0(版本号)/modules/xfeature2d/opencv_xfeature2d project /src/sift.cpp
cv namespace
xfeature2d namespace
SIFT的子类 父类/基类
adjustLocalExtre ma()调整极值函数
图像尺度空间的构建
1.1图像初始化函数 函数功能:将输入图像转化为灰度图,并设置图像初始尺度 c++:static Mat createInitialImage( const Mat& img, bool double ImageSize, float sigma ) 入口参数: ①参数const Mat& img:输入图像 ②参数bool double ImageSize:是否将初始图像扩大两倍,若值为1,则图像扩大为原来两倍 ③参数float sigma:设定图像的初始尺度 返回值:无
SIFT_Impl::detectAndCompute (image, noArray(), keypoints, descriptors, true)
buildDoGPyramid() 构建DOG金字塔函 数 unpackOctave()
calcDescriptors() 计算关键点描述子函数
calcSIFTDescriptor
PART TREE .检测关键点部分
函数功能:检测图片中的关键点 ①参数image:输入图片 ②参数mask:无掩模 ③参数keypoints:关键点容器 ④参数noArray():无描述子 ⑤参数false:不使用给定的关键点
SIFT_Impl::detectAndCompute(image, mask, keypoints, noArray(), false);
Feature2D::compute( InputArray image, std::vector<KeyPoint>& keypoints, OutputArray descriptors )
调用了 计算描述子函数 SIFT_Impl::detectAndCompute(image, noArray(), keypoints, descriptors, true);
计算sift特征描述子
3.2计算sift特征描述子 函数功能:计算特征点描述符 calcDescriptors函数 static void calcDescriptors(const std::vector<Mat>& gpyr, const std::vector<KeyPoint>& keypoints, Mat& descriptors, int nOctaveLayers, int firstOctave ) 入口参数: ①参数const std::vector<Mat>& gpyr:存放高斯金字塔图片的容器 ②参数const std::vector<KeyPoint>& keypoints:存放关键点的容器 ③参数Mat& descriptors:描述子矩阵 ④参数int nOctaveLayers:高斯金字塔层数 ⑤参数int firstOctave:如果原图像扩大两倍,则为-1,如果没有,则为0 返回值:无 说明:计算sift特征描述子要用高斯金字塔,dog金字塔只用来求取极值点 int d=SIFT_DESCR_WIDTH=4,n=SIFT_DESCR_HIST_BINS=8 float size=kpt.size*scale 计算特征点的特征矢量calcSIFTDescriptor(img, ptf, angle, size*0.5f, d, n, descriptors.ptr<float>((int)i))
PART FOUR.关键点描述子
函数功能:计算图片中的关键点描述子 ①参数image:输入图片 ②参数noArray():无掩模 ③参数keypoints:关键点容器 ④参数descriptors:描述子 ⑤参数true:使用给定的关键点
createInitialImage() 图像初始化函数
buildGaussianPyra mid()构建高斯金字塔 函数
说明:
设f(i,j)是y轴为i、x轴为j的图像像素值,则在 (i,j)点处的一阶、二阶及二阶混合偏导为:
ˆ ( X X ) 得: 其中令 X 0
令
ˆ) f ( X ˆ : 0 解得 X ˆ X
ˆ ) 进行筛选去除对比度低的点,在opencv中, 再对 f ( X 使用下面的公式来判断其是否为不稳定的极值:
接下来判断偏移量在每个维度的偏差是否大 于0.5,若不大于直接保留,若大于进行迭代 插值处理。在设置的迭代次数内修正成功则 保留,否则舍弃。
去除边缘响应较强的点,具体பைடு நூலகம்程序中的计算同上:
计算关键点主方向函数 函数功能:为特征点分配主方向 static float calcOrientationHist( const Mat& img, Point pt, int radius, float sigma, float* hist, int n ) 入口参数: ①参数const Mat& img:当前特征点所在的图像 ②参数Point pt:关键点位置 ③参数int radius:指统计在以关键点为中心,以radius=3*1.5sigma为半径的区域为作为该关键 点的邻域,以统计直方图的形式来确定主方向 ④参数float sigma:这里的sigma是指相对于当前组第一层图像的尺度来说的 ⑤参数float* hist:定义了hist指针用于存放直方图 ⑥参数int n:直方图的条数 返回值:直方图的主峰值 说明:直方图平滑处理;opencv使用的平滑公式为: 由于直方图代表的只是一个角度范围,想 要得到更精确的方向角度值,需要对离散 的梯度方向直方图进行插值拟合处理,拟 合公式为: