您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 资本运营 > SIFT系列02--SIFT源码详细注释
SIFT系列02--SIFT源码详细注释,保留每一步运算的中间结果(2013-04-2718:30:38)关于sift算法的原理有很多文档,本来想整理到BLOG,但是考虑到排版比较麻烦,就不弄了。把opencv里面的sift源码详细注释了一下,把相关函数重新整合到SIFT的类里面,这样就可以用这个类而不用opencv的sift接口来提取特征点,用此方法提取特征点的速度上也有很明显的提升,说明OpenCV用来做具体的工程效率肯定是跟不上的,还是得改成纯C、C++。SIFT每一步的中间结果也保存下来,包括所有的高斯金字塔图像,DOG图像,特征点坐标,描述符矩阵等。方便自己更好的理解。保存结果:1、高斯金字塔2、dog金字塔3、特征点坐标4、特征点描述符5、特征点程序代码:一、sift.h文件#includeopencv2/features2d/features2d.hpp#includeopencv2\opencv.hpp#includeiostream#includefstreamusingnamespacecv;namespacecv{classCV_EXPORTS_WSIFT:publicFeature2D{public:CV_PROP_RWintnfeatures;CV_PROP_RWintnOctaveLayers;CV_PROP_RWdoublecontrastThreshold;CV_PROP_RWdoubleedgeThreshold;CV_PROP_RWdoublesigma;explicitSIFT(intnfeatures=0,intnOctaveLayers=3,doublecontrastThreshold=0.04,doubleedgeThreshold=10,doublesigma=1.6);//!returnsthedescriptorsizeinfloats(128)//返回描述符维度intdescriptorSize()const;//!returnsthedescriptortype//返回描述符类型intdescriptorType()const;//!findsthekeypointsusingSIFTalgorithm//重载操作符(),用SIFT算法找到关键点voidoperator()(InputArrayimg,InputArraymask,vector&keypoints)const;//!findsthekeypointsandcomputesdescriptorsforthemusingSIFTalgorithm.//!Optionallyitcancomputedescriptorsfortheuser-providedkeypoints//重载操作符(),用SIFT算法找关键点并计算描述符。设置最后一个参数可以计算用户自己提供的特征点的描述符//mask:Optionalinputmaskthatmarkstheregionswhereweshoulddetectfeatures.voidoperator()(InputArrayimg,InputArraymask,vector&keypoints,OutputArraydescriptors,booluseProvidedKeypoints=false)const;AlgorithmInfo*info()const;staticMatcreateInitialImage(constMat&img,booldoubleImageSize,floatsigma);voidbuildGaussianPyramid(constMat&base,vector&pyr,intnOctaves)const;voidbuildDoGPyramid(constvector&pyr,vector&dogpyr)const;voidfindScaleSpaceExtrema(constvector&gauss_pyr,constvector&dog_pyr,vector&keypoints)const;staticvoidcalcSIFTDescriptor(constMat&img,Point2fptf,floatori,floatscl,intd,intn,float*dst);staticvoidcalcDescriptors(constvector&gpyr,constvector&keypoints,Mat&descriptors,intnOctaveLayers);protected:voiddetectImpl(constMat&image,vector&keypoints,constMat&mask=Mat())const;voidcomputeImpl(constMat&image,vector&keypoints,Mat&descriptors)const;//CV_PROP_RWbooldoubleImageSize=false;};}二、sift.cpp//Sift01.cpp:定义控制台应用程序的入口点。//#includestdafx.h#includesift.h//defaultnumberofsampledintervalsperoctavestaticconstintSIFT_INTVLS=3;//defaultsigmaforinitialgaussiansmoothingstaticconstfloatSIFT_SIGMA=1.6f;//defaultthresholdonkeypointcontrast|D(x)|staticconstfloatSIFT_CONTR_THR=0.04f;//defaultthresholdonkeypointratioofprinciplecurvaturesstaticconstfloatSIFT_CURV_THR=10.f;//doubleimagesizebeforepyramidconstruction?staticconstboolSIFT_IMG_DBL=true;//defaultwidthofdescriptorhistogramarraystaticconstintSIFT_DESCR_WIDTH=4;//defaultnumberofbinsperhistogramindescriptorarraystaticconstintSIFT_DESCR_HIST_BINS=8;//assumedgaussianblurforinputimagestaticconstfloatSIFT_INIT_SIGMA=0.5f;//widthofborderinwhichtoignorekeypointsstaticconstintSIFT_IMG_BORDER=5;//maximumstepsofkeypointinterpolationbeforefailurestaticconstintSIFT_MAX_INTERP_STEPS=5;//defaultnumberofbinsinhistogramfororientationassignmentstaticconstintSIFT_ORI_HIST_BINS=36;//determinesgaussiansigmafororientationassignmentstaticconstfloatSIFT_ORI_SIG_FCTR=1.5f;//determinestheradiusoftheregionusedinorientationassignmentstaticconstfloatSIFT_ORI_RADIUS=3*SIFT_ORI_SIG_FCTR;//orientationmagnituderelativetomaxthatresultsinnewfeaturestaticconstfloatSIFT_ORI_PEAK_RATIO=0.8f;//determinesthesizeofasingledescriptororientationhistogramstaticconstfloatSIFT_DESCR_SCL_FCTR=3.f;//thresholdonmagnitudeofelementsofdescriptorvectorstaticconstfloatSIFT_DESCR_MAG_THR=0.2f;//factorusedtoconvertfloating-pointdescriptortounsignedcharstaticconstfloatSIFT_INT_DESCR_FCTR=512.f;staticconstintSIFT_FIXPT_SCALE=48;//std::ofstreamfout(sigma.txt);//保存尺度MatSIFT::createInitialImage(constMat&img,booldoubleImageSize,floatsigma){Matgray,gray_fpt;if(img.channels()==3||img.channels()==4)cvtColor(img,gray,COLOR_BGR2GRAY);//原始图像转灰度elseimg.copyTo(gray);//缩放并转换到另外一种数据类型,深度转换为CV_16S避免外溢。(48,0)为缩放参数//灰度值拉伸了48倍,CV_16S避免外溢gray.convertTo(gray_fpt,CV_16S,SIFT_FIXPT_SCALE,0);//SIFT_FIXPT_SCALE=48floatsig_diff;//默认传进来的doubleImageSIze不是flase吗?这里应该是if(!doubleImageSize)啊??if(doubleImageSize){//sigma=1.6,SIFT_INIT_SIGMA=0.5sig_diff=sqrtf(std::max(sigma*sigma-SIFT_INIT_SIGMA*SIFT_INIT_SIGMA*4,0.01f));Matdbl;resize(gray_fpt,dbl,Size(gray.cols*2,gray.rows*2),0,0,INTER_LINEAR);//长宽乘2GaussianBlur(dbl,dbl,Size(),sig_diff,sig_diff);returndbl;}else{sig_diff=sqrtf(std::max(sigma*sigma-SIFT_INIT_SIGMA*SIFT_INIT_SIGMA,0.01f));GaussianBlur(gray_fpt,gray_fpt,Size(),sig_diff,sig_diff);returngray_fpt;}}voidSIFT::buildGaussianPyramid(constMat&base,vector&pyr,intnOctaves)const{vectorsig(nOctaveLayers+3);pyr.resize(nOctaves*(nOctaveLayers+3));//pyr保存所有组所有层//precomputeGaussiansigmasusingthefollowingformula://\sigma_{total}^2=\sigma_{i}^2+\sigma_{i-1}^2//计算第0组每层的尺度因子sig[i],第0组第0层已经模糊过,所有只有5层需要模糊sig[0]=sigma;//第0层尺度为sigma//fout每层的尺度为:\n;//foutsig[0]'\n';doublek=pow(2.,1./nOctaveLayers);for(inti=1;inOctaveLayers+3;i++){doublesig_prev=pow(k,(double)(i-1
本文标题:SIFT系列02--SIFT源码详细注释
链接地址:https://www.777doc.com/doc-3352859 .html