【VC++开源代码栏目提醒】:文章导读:在新的一年中,各位网友都进入紧张的学习或是工作阶段。
网学会员整理了VC++开源代码-[工学]SIFT算法实现及代码详解 - 讲义教程的相关内容供大家参考,祝大家在新的一年里工作和学习顺利!
经典算法SIFT实现即
代码解释 以下便是sift源码库编译后的效果图 为了给有兴趣实现sift算法的朋友提供个参考特整理此文如下。
要了解什么是sift算法请参考九、图像特征提取与匹配之SIFT算法。
ok咱们下面就来利用Rob Hess维护的sift 库来实现sift算法 首先请下载Rob Hess维护的sift 库 http://blogs.oregonstate.edu/hess/code/sift/ 下载Rob Hess的这个压缩包后如果直接解
压缩直接编译那么会出现下面的错误提示 编译提示:error C1083: Cannot open include file: cxcore.h: No such file or directory找不到这个头文件。
这个错误是因为你还没有安装opencv因为cxcore.h和cv.h是
开源的OPEN CV头文件不是
VC的默认安装文件所以你还得下载OpenCV并进行安装。
然后可以在OpenCV文件夹下找到你所需要的头文件了。
据网友称截止2010年4月4日还没有在
VC6.0下成功使用opencv2.0的案例。
所以如果你是
VC6.0的用户请下载opencv1.0版本。
vs的话opencv2.01.0任意下载。
以下咱们就以
vc6.0为平台举例下载并安装opencv1.0版本、gsl等。
当然你也可以用vs编译同样下载opencv具体版本不受限制、gsl等。
请按以下步骤操作 一、下载opencv1.0 http://sourceforge.net/projects/opencvlibrary/files/opencv-win/1.0/OpenCV_1.0.exe/download 二、安装opencv1.0配置Windows环境变量 1、安装注意假如你是将OpenCV安装到C:/Program Files/OpenCV如果你安装的时候选择不是安装在C盘则下面所有对应的C盘都改为你所安装在的那个“X盘”即可在安装时选择quot将/OpenCV/bin加入系统变量quot打上“勾”。
Add/OpenCV/bin to the systerm PATH。
这一步确认选上了之后下面的检查环境变量的步骤便可免去 2、检查环境变量。
为了确保上述步骤中加入了系统变量在安装opencv1.0成功后还得检查C:/Program Files/OpenCV/bin是否已经被加入到环境变量PATH如果没有请加入。
3、最后是配置Visual C 6.0。
全局设置 菜单Tools-gtOptions-gtDirectories先设置lib路径选择Library files在下方填入路径 C:/Program Files/OpenCV/lib 然后选择include files在下方填入路径参考下图 C:/Program Files/OpenCV/cxcore/include C:/Program Files/OpenCV/cv/include C:/Program Files/OpenCV/cvaux/include C:/Program Files/OpenCV/ml/include C:/Program Files/OpenCV/otherlibs/highgui C:/Program Files/OpenCV/otherlibs/cvcam/include 最后选择source files在下方填入路径 C:/Program Files/OpenCV/cv/src C:/Program Files/OpenCV/cxcore/src C:/Program Files/OpenCV/cvaux/src C:/Program Files/OpenCV/otherlibs/highgui C:/Program Files/OpenCV/otherlibs/cvcam/src/windows 项目设置 每创建一个将要使用OpenCV的
VC Project都需要给它指定需要的lib。
菜单Project-gtSettings然后将Setting for选为All Configurations然后选择右边的link标签在Object/library modules附加上 cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.lib 当然你不需要这么多lib你可以只添加你需要的lib见下图 三、下载gslgsl也是一个库也需要下载 http://sourceforge.net/projects/gnuwin32/files/gsl/1.8/gsl-1.8.exe/download。
在编译时候GSL也是和OpenCV一样要把头文件和lib的路径指定好。
四、配置gsl 将C:/WinGsl/bin中的WinGsl.dll和WinGslD.dll复制到C:/
VC6.0/Bin将整个Gsl目录复制到C:/
VC6.0/Bin下lib目录下的所有.lib文件全部复制到C:/
VC6.0/Lib下。
然后在toolsoptionsdirectories中将C:/WinGsl下的libgsl分别加入到库文件和头文件的
搜索路径中。
以下是可能会出现的错误情况处理 I、OpenCV安装后“没有找到cxcore100.dll”的错误处理 在安装时选择“将/OpenCV/bin加入
系统变量”Add/OpenCV/bin to the systerm PATH。
但该选项并不一定能成功添加到系统变量如果编写的程序在运行时出现“没有找到cxcore100.dll因为这个应用程序未能启动。
重新安装应用
程序可能会修复此
问题。
”的错误。
手动在我的电脑-gt属性-gt高级-gt环境变量-gt系统变量-gtpath添加c:/program files/opencv/bin添加完成后需要重启
计算机。
II、
vc6.0下配置了一下可是编译程序时遇到如下一个错误 Linking... LINK : fatal error LNK1104: cannot open filequotodbccp32.libcxcore.libquot 可能是在工程设置的时候添加连接库时没加空格或.来把两个文件名odbccp32.lib cxcore.lib分开。
注意每一次操作后记得保存。
若经过以上所有的步骤之后如果还不能正常编译那就是还要稍微修改下你下载的Rob Hess
代码。
ok日后若有空再好好详细剖析下此sift的源码。
最后祝你编译顺利。
完。
SIFT
代码详解 这是一个很强大的算法主要用于图像配准和物体识别等领域但是其计算量相比也比较大性价比比较高的算法包括PCA-SIFT和SURF其中OpenCV提供了SURF算法但是为了方便理解。
这里给出了Rob Hess所实现的SIFT算法的实现以及注释结合我自己的理解如果您有关于SIFT算法不理解的地方咱们可以一起交流一下。
或者您认为不详细的地方提出来。
SIFT算法的主要实现在sift.c这个文件其主要流程为 1首先创建初始图像即通过将图像转换为32位的灰度图然后将图像使用三次插值来方大之后通过高斯模糊处理 2在此基础上进行高斯金字塔的构建以及高斯差分金字塔的构建 3对图像进行极值点检测 4计算特征向量的尺度 5调整图像大小 6计算特征的方向 7计算描述子其中包括计算二维方向直方图并转换直方图为特征描述子 首先给出sift算法的整体框架
代码 输入参数 img为输入图像 feat为所要提取的特征指针 intvl指的是高斯金字塔和差分金字塔的层数 sigma指的是图像初始化过程中高斯模糊所使用的参数 contr_thr是归一化之后的去除不稳定特征的阈值 curv_thr指的是去除边缘的特征的主曲率阈值 img_dbl是是否将图像放大为之前的两倍 descr_with用来计算特征描述子的方向直方图的宽度 descr_hist_bins是直方图中的条数 cpp view plaincopy 1. int _sift_features IplImage img struct feature feat int intvls 2. double sigma double contr_thr int curv_thr 3. int img_dbl int descr_width int descr_hist_bins 4. 5. IplImage init_img 6. IplImage gauss_pyr dog_pyr 7. CvMemStorage storage 8. CvSeq features 9. int octvs i n 0 10. 11. / check arguments / 12. if img 13. fatal_error quotNULL pointer error s line dquot __FILE__ __LINE__ 14. 15. if feat 16. fatal_error quotNULL pointer error s line dquot __FILE__ __LINE__ 17. 18. / build scale space pyramid smallest dimension of top level is 4 pixels / 19. / 构建高斯尺度空间金字塔顶层最小的为4像素 / 20. init_img create_init_img img img_dbl sigma 21. octvs log double MIN init_img-gtwidth init_img-gtheight / log2.0 - 2 22. //构建高斯金字塔和高斯差分金字塔 23. gauss_pyr build_gauss_pyr init_img octvs intvls sigma 24. dog_pyr build_dog_pyr gauss_pyr octvs intvls 25. 26. storage cvCreateMemStorage 0 27. 28. //尺度空间极值点检测 29. features scale_space_extrema dog_pyr octvs intvls contr_thr 30. curv_thr storage 31. 32. //画出去除低对比度的极值点 33. //draw_extrempointimg features 34. 35. 36. 37. 38. //计算特征向量的尺度 39. calc_feature_scales features sigma intvls 40. if img_dbl 41. adjust_for_img_dbl features 42. //计算特征的方向 43. calc_feature_oris features gauss_pyr 44. //计算描述子包括计算二维方向直方图和转换其为特征描述子 45. compute_descriptors features gauss_pyr descr_width descr_hist_bins 46. 47. / sort features by decreasing scale and move from CvSeq to array / 48. cvSeqSort features CvCmpFuncfeature_cmp NULL 49. n features-gttotal 50. feat static_castltfeature gt calloc n sizeofstruct feature 51. feat static_castltfeature gt cvCvtSeqToArray features feat CV_WHOLE_SEQ 52. 53. 54. 55. 56. for i 0 i lt n i 57. 58. free feati.feature_data 59. feati.feature_data NULL 60. 61. 62. cvReleaseMemStorage ampstorage 63. cvReleaseImage ampinit_img 64. release_pyr ampgauss_pyr octvs intvls 3 65. release_pyr ampdog_pyr octvs intvls 2 66. return n 67. 1初始化图像 输入参数 这里不需要解释了 该函数主要用来初始化图像转换图像为32位灰度图以及进行高斯模糊。
cpp view plaincopy 1. static IplImage create_init_img IplImage img int img_dbl double sigma 2. 3. IplImage gray dbl 4. float sig_diff 5. 6. gray convert_to_gray32 img 7. if img_dbl 8. 9. sig_diff sqrt sigma sigma - SIFT_INIT_SIGMA SIFT_INIT_SIGMA 4 10. dbl cvCreateImage cvSize img-gtwidth2 img-gtheight2 11. IPL_DEPTH_32F 1 12. cvResize gray dbl CV_INTER_CUBIC 13. cvSmooth dbl dbl CV_GAUSSIAN 0 0 sig_diff sig_diff 14. cvReleaseImage ampgray 15. return dbl 16. 17. else 18. 19. sig_diff sqrt sigma sigma - SIFT_INIT_SIGMA SIFT_INIT_SIGMA 20. cvSmooth gray gray CV_GAUSSIAN 0 0 sig_diff sig_diff 21. return gray 22. 23. 2构建高斯金字塔 输入参数 octvs是高斯金字塔的组 invls是高斯金字塔的层数 sigma是初始的高斯模糊参数后续也通过它计算每一层所使用的sigma cpp view plaincopy 1. ltspan stylequotfont-size:13pxquotgtstatic IplImage build_gauss_pyr IplImage base int octvsint intvls double sigma 2. 3. IplImage gauss_pyr 4. double sig static_castltdouble gt calloc intvls 3 sizeofdouble 5. double sig_total sig_prev k 6. int i o 7. 8. gauss_pyr static_castltIplImage gt calloc octvs sizeof IplImage 9. for i 0 i lt octvs i 10. gauss_pyri static_castltIplImage gt calloc intvls 3 sizeof IplImage 11. 12. / 13. precompute Gaussian sigmas using the following formula: 14. 预计算每次高斯模糊的sigma 15. 16. sigma_total2 sigma_i2 sigma_i-12 17. / 18. sig0 sigma 19. k pow 2.0 1.0 / intvls 20. for i 1 i lt intvls 3 i 21. 22. sig_prev pow k i - 1 sigma 23. sig_total sig_prev k 24. sigi sqrt sig_total sig_total - sig_prev sig_prev 25. 26. 27. 28. for o 0 o lt octvs o 29. for i 0 i lt intvls 3 i 30. 31. //对每一层进行降采样形成高斯金字塔的每一层 32. if o 0 ampamp i 0 33. gauss_pyroi cvCloneImagebase 34. 35. / base of new octvave is halved image from end of previous octave / 36. //每一组的第一层都是通过对前面一组的第一层降采样实现的 37. else if i 0 38. gauss_pyroi downsample gauss_pyro-1intvls 39. 40. / blur the current octaves last image to create the next one / 41. //每一组的其他层则使通过使用不同sigma的高斯模糊来进行处理 42. else 43. 44. gauss_pyroi cvCreateImage cvGetSizegauss_pyroi-1 45. IPL_DEPTH_32F 1 46. cvSmooth gauss_pyroi-1 gauss_pyroi 47. CV_GAUSSIAN 0 0 sigi sigi 48. 49. 50. 51. free sig 52. return gauss_pyr 53. lt/spangt 降采样处理 输入参数 不解释 这就是降采样其实就是将图像通过最近邻算法缩小为原来的一半 cpp view plaincopy 1. static IplImage downsample IplImage img 2. 3. IplImage smaller cvCreateImage cvSizeimg-gtwidth / 2 img-gtheight / 2 4. img-gtdepth img-gtnChannels 5. cvResize img smaller CV_INTER_NN 6. 7. return smaller 8. 3构建高斯差分金字塔 输入参数 不解释了参见上面的说明即可 实际上差分金字塔的构成是通过对相邻层的图像进行相减获得的 cpp view plaincopy 1. ltspan stylequotfont-size:16pxquotgtstatic IplImage build_dog_pyr IplImage gauss_pyr int octvs int intvls 2. 3. IplImage dog_pyr 4. int i o 5. 6. dog_pyr static_castltIplImage gt calloc octvs sizeof IplImage 7. for i 0 i lt octvs i 8. dog_pyri static_castltIplImage gt calloc intvls 2 sizeofIplImage 9. 10. for o 0 o lt octvs o 11. for i 0 i lt intvls 2 i 12. 13. dog_pyroi cvCreateImage cvGetSizegauss_pyroi 14. IPL_DEPTH_32F 1 15. cvSub gauss_pyroi1 gauss_pyroi dog_pyroi NULL 16. 17. 18. return dog_pyr 19. lt/spangt 4极值点检测 输入参数 contr_thr是去除对比度低的点所采用的阈值 curv_thr是去除边缘特征的阈值 cpp view plaincopy 1. static CvSeq scale_space_extrema IplImage dog_pyr int octvs int intvls 2. double contr_thr int curv_thr 3. CvMemStorage storage 4. 5. CvSeq features 6. double prelim_contr_thr 0.5 contr_thr / intvls 7. struct feature feat 8. struct detection_data ddata 9. int o i r c 10. 11. features cvCreateSeq 0 sizeofCvSeq sizeofstruct feature storage 12. for o 0 o lt octvs o 13. for i 1 i lt intvls i 14. forr SIFT_IMG_BORDER r lt dog_pyro0-gtheight-SIFT_IMG_BORDER r 15. forc SIFT_IMG_BORDER c lt dog_pyro0-gtwidth-SIFT_IMG_BORDER c 16. / perform preliminary check on contrast / 17. if ABS pixval32f dog_pyroi r c gt prelim_contr_thr 18. if is_extremum dog_pyr o i r c 19. 20. feat interp_extremumdog_pyr o i r c intvls contr_thr 21. if feat 22. 23. ddata feat_detection_data feat 24. if is_too_edge_like dog_pyrddata-gtoctvddata-gtintvl 25. ddata-gtr ddata-gtc curv_thr 26. 27. cvSeqPush features feat 28. 29. else 30. free ddata 31. free feat 32. 33. 34. 35. return features 36. SIFT_IMG_BORDER是预定义的图像边缘 通过和对比度阈值比较去掉低对比度的点 而通过is_extremum来判断是否为极值点如果是则通过极值点插值的方式获取亚像素的极值点的位置。
然后通过is_too_eage_like和所给的主曲率阈值判断是否为边缘点 判断是否为极值点 其原理为:通过和高斯金字塔的上一层的9个像素本层的除了本像素自己的其他的8个像素和下一层的9个像素进行比较看是否为这26个像素中最小的一个或者是否为最大的一个如果是则为极值点。
cpp view plaincopy 1. static int is_extremum IplImage dog_pyr int octv int intvl int r int c 2. 3. float val pixval32f dog_pyroctvintvl r c 4. int i j k 5. 6. / check for maximum / 7. if val gt 0 8. 9. for i -1 i lt 1 i 10. for j -1 j lt 1 j 11. for k -1 k lt 1 k 12. if val lt pixval32f dog_pyroctvintvli r j c k 13. return 0 14. 15. 16. / check for minimum / 17. else 18. 19. for i -1 i lt 1 i 20. for j -1 j lt 1 j 21. for k -1 k lt 1 k 22. if val gt pixval32f dog_pyroctvintvli r j c k 23. return 0 24. 25. 26. return 1 27. 获取亚像素的极值点的位置 cpp view plaincopy 1. static struct feature interp_extremum IplImage dog_pyr int octv int intvl 2. int r int c int intvls double contr_thr 3. 4. struct feature feat 5. struct detection_data ddata 6. double xi xr xc contr//分别为亚像素的intvalrowcol的偏移offset和对比度 7. int i 0 8. 9. while i lt SIFT_MAX_INTERP_STEPS //重新确定极值点并重新定位的操作只能循环 5次 10. 11. interp_step dog_pyr.