1 AKAZE and ORB planar tracking {#tutorial_akaze_tracking} 2 ============================= 3 4 Introduction 5 ------------ 6 7 In this tutorial we will compare *AKAZE* and *ORB* local features using them to find matches between 8 video frames and track object movements. 9 10 The algorithm is as follows: 11 12 - Detect and describe keypoints on the first frame, manually set object boundaries 13 - For every next frame: 14 -# Detect and describe keypoints 15 -# Match them using bruteforce matcher 16 -# Estimate homography transformation using RANSAC 17 -# Filter inliers from all the matches 18 -# Apply homography transformation to the bounding box to find the object 19 -# Draw bounding box and inliers, compute inlier ratio as evaluation metric 20 21 ![](images/frame.png) 22 23 Data 24 ---- 25 26 To do the tracking we need a video and object position on the first frame. 27 28 You can download our example video and data from 29 [here](https://docs.google.com/file/d/0B72G7D4snftJandBb0taLVJHMFk). 30 31 To run the code you have to specify input and output video path and object bounding box. 32 @code{.none} 33 ./planar_tracking blais.mp4 result.avi blais_bb.xml.gz 34 @endcode 35 36 Source Code 37 ----------- 38 39 @include cpp/tutorial_code/features2D/AKAZE_tracking/planar_tracking.cpp 40 41 Explanation 42 ----------- 43 44 ### Tracker class 45 46 This class implements algorithm described abobve using given feature detector and descriptor 47 matcher. 48 49 - **Setting up the first frame** 50 @code{.cpp} 51 void Tracker::setFirstFrame(const Mat frame, vector<Point2f> bb, string title, Stats& stats) 52 { 53 first_frame = frame.clone(); 54 (*detector)(first_frame, noArray(), first_kp, first_desc); 55 stats.keypoints = (int)first_kp.size(); 56 drawBoundingBox(first_frame, bb); 57 putText(first_frame, title, Point(0, 60), FONT_HERSHEY_PLAIN, 5, Scalar::all(0), 4); 58 object_bb = bb; 59 } 60 @endcode 61 We compute and store keypoints and descriptors from the first frame and prepare it for the 62 output. 63 64 We need to save number of detected keypoints to make sure both detectors locate roughly the same 65 number of those. 66 67 - **Processing frames** 68 69 -# Locate keypoints and compute descriptors 70 @code{.cpp} 71 (*detector)(frame, noArray(), kp, desc); 72 @endcode 73 74 To find matches between frames we have to locate the keypoints first. 75 76 In this tutorial detectors are set up to find about 1000 keypoints on each frame. 77 78 -# Use 2-nn matcher to find correspondences 79 @code{.cpp} 80 matcher->knnMatch(first_desc, desc, matches, 2); 81 for(unsigned i = 0; i < matches.size(); i++) { 82 if(matches[i][0].distance < nn_match_ratio * matches[i][1].distance) { 83 matched1.push_back(first_kp[matches[i][0].queryIdx]); 84 matched2.push_back( kp[matches[i][0].trainIdx]); 85 } 86 } 87 @endcode 88 If the closest match is *nn_match_ratio* closer than the second closest one, then it's a 89 match. 90 91 -# Use *RANSAC* to estimate homography transformation 92 @code{.cpp} 93 homography = findHomography(Points(matched1), Points(matched2), 94 RANSAC, ransac_thresh, inlier_mask); 95 @endcode 96 If there are at least 4 matches we can use random sample consensus to estimate image 97 transformation. 98 99 -# Save the inliers 100 @code{.cpp} 101 for(unsigned i = 0; i < matched1.size(); i++) { 102 if(inlier_mask.at<uchar>(i)) { 103 int new_i = static_cast<int>(inliers1.size()); 104 inliers1.push_back(matched1[i]); 105 inliers2.push_back(matched2[i]); 106 inlier_matches.push_back(DMatch(new_i, new_i, 0)); 107 } 108 } 109 @endcode 110 Since *findHomography* computes the inliers we only have to save the chosen points and 111 matches. 112 113 -# Project object bounding box 114 @code{.cpp} 115 perspectiveTransform(object_bb, new_bb, homography); 116 @endcode 117 118 If there is a reasonable number of inliers we can use estimated transformation to locate the 119 object. 120 121 Results 122 ------- 123 124 You can watch the resulting [video on youtube](http://www.youtube.com/watch?v=LWY-w8AGGhE). 125 126 *AKAZE* statistics: 127 @code{.none} 128 Matches 626 129 Inliers 410 130 Inlier ratio 0.58 131 Keypoints 1117 132 @endcode 133 134 *ORB* statistics: 135 @code{.none} 136 Matches 504 137 Inliers 319 138 Inlier ratio 0.56 139 Keypoints 1112 140 @endcode 141