java opencv surf_OpenCV中的SURF算法介绍

SURF:speed up robust feature,翻译为快速鲁棒特征。首先就其中涉及到的特征点和描述符做一些简单的介绍:

特征点和描述符

特征点分为两类:狭义特征点和广义特征点。狭义特征点的位置本身具有常规的属性意义,比如角点、交叉点等等。而广义特征点是基于区域定义的,它本身的位置不具备特征意义,只代表满足一定特征条件的特征区域的位置。广义特征点可以是某特征区域的任一相对位置。这种特征可以不是物理意义上的特征,只要满足一定的数学描述就可以,因而有时是抽象的。因此,从本质上说,广义特征点可以认为是一个抽象的特征区域,它的属性就是特征区域具备的属性;称其为点,是将其抽象为一个位置概念。

特征点既是一个点的位置标识,同时也说明它的局部邻域具有一定的模式特征。事实上,特征点是一个具有一定特征的局部区域的位置标识,称其为点,是将其抽象为一个位置概念,以便于确定两幅图像中同一个位置点的对应关系而进行图像匹配。所以在特征匹配过程中是以该特征点为中心,将邻域的局部特征进行匹配。也就是说在进行特征匹配时首先要为这些特征点(狭义和广义)建立特征描述,这种特征描述通常称之为描述符。

一个好的特征点需要有一个好的描述方法将其表现出来,它涉及到的是图像匹配的一个准确性。因此在基于特征点的图像拼接和图像配准技术中,特征点和描述符同样重要。

OpenCv中SURF的demo

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include

3 #include "opencv2/core/core.hpp"

4 #include "opencv2/features2d/features2d.hpp"

5 #include "opencv2/highgui/highgui.hpp"

6 #include "opencv2/calib3d/calib3d.hpp"

7

8 using namespacecv;9

10 voidreadme();11

12 /** @function main*/

13 int main( int argc, char**argv )14 {15 if( argc != 3)16 { readme(); return -1; }17

18 Mat img_object = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );19 Mat img_scene = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );20

21 if( !img_object.data || !img_scene.data )22 { std::cout<< "--(!) Error reading images" << std::endl; return -1; }23

24 //-- Step 1: Detect the keypoints using SURF Detector

25 int minHessian = 400;26

27 SurfFeatureDetector detector( minHessian );28

29 std::vectorkeypoints_object, keypoints_scene;30

31 detector.detect( img_object, keypoints_object );32 detector.detect( img_scene, keypoints_scene );33

34 //-- Step 2: Calculate descriptors (feature vectors)

35 SurfDescriptorExtractor extractor;36

37 Mat descriptors_object, descriptors_scene;38

39 extractor.compute( img_object, keypoints_object, descriptors_object );40 extractor.compute( img_scene, keypoints_scene, descriptors_scene );41

42 //-- Step 3: Matching descriptor vectors using FLANN matcher

43 FlannBasedMatcher matcher;44 std::vector< DMatch >matches;45 matcher.match( descriptors_object, descriptors_scene, matches );46

47 double max_dist = 0; double min_dist = 100;48

49 //-- Quick calculation of max and min distances between keypoints

50 for( int i = 0; i < descriptors_object.rows; i++)51 { double dist =matches[i].distance;52 if( dist < min_dist ) min_dist =dist;53 if( dist > max_dist ) max_dist =dist;54 }55

56 printf("-- Max dist : %f \n", max_dist );57 printf("-- Min dist : %f \n", min_dist );58

59 //-- Draw only "good" matches (i.e. whose distance is less than 3*min_dist )

60 std::vector< DMatch >good_matches;61

62 for( int i = 0; i < descriptors_object.rows; i++)63 { if( matches[i].distance < 3*min_dist )64 { good_matches.push_back( matches[i]); }65 }66

67 Mat img_matches;68 drawMatches( img_object, keypoints_object, img_scene, keypoints_scene,69 good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),70 vector(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );71

72 //-- Localize the object

73 std::vectorobj;74 std::vectorscene;75

76 for( int i = 0; i < good_matches.size(); i++)77 {78 //-- Get the keypoints from the good matches

79 obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt );80 scene.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );81 }82

83 Mat H =findHomography( obj, scene, CV_RANSAC );84

85 //-- Get the corners from the image_1 ( the object to be "detected" )

86 std::vector obj_corners(4);87 obj_corners[0] = cvPoint(0,0); obj_corners[1] = cvPoint( img_object.cols, 0);88 obj_corners[2] = cvPoint( img_object.cols, img_object.rows ); obj_corners[3] = cvPoint( 0, img_object.rows );89 std::vector scene_corners(4);90

91 perspectiveTransform( obj_corners, scene_corners, H);92

93 //-- Draw lines between the corners (the mapped object in the scene - image_2 )

94 line( img_matches, scene_corners[0] + Point2f( img_object.cols, 0), scene_corners[1] + Point2f( img_object.cols, 0), Scalar(0, 255, 0), 4);95 line( img_matches, scene_corners[1] + Point2f( img_object.cols, 0), scene_corners[2] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4);96 line( img_matches, scene_corners[2] + Point2f( img_object.cols, 0), scene_corners[3] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4);97 line( img_matches, scene_corners[3] + Point2f( img_object.cols, 0), scene_corners[0] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4);98

99 //-- Show detected matches

100 imshow( "Good Matches & Object detection", img_matches );101

102 waitKey(0);103 return 0;104 }105

106 /** @function readme*/

107 voidreadme()108 { std::cout << "Usage: ./SURF_descriptor " << std::endl; }

View Code

有了对特征点和描述符的简单认识后,对上述代码就能有更好的理解了。

SURF算法的具体实现过程

整理了网上的一些资料:

surf算法原理,有一些简单介绍(1)

2.  surf算法原理,有一些简单介绍(2)

3 . 特征点检测学习_2(surf算法)

其他

1 //DMatch function

2 DMatch(int queryIdx, int trainIdx, float distance)

其中 queryIdx 和 trainIdx 对应的特征点索引由match函数决定,例如:

1 //按如下顺序使用

2 match(descriptor_for_keypoints1, descriptor_for_keypoints2, matches)

则queryIdx 和 trainIdx分别对应keypoints1和keypoints2。

2013-11-05

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值