目标 ? 理解 FAST 算法的基础 ? 使用 OpenCV 中的 FAST 算法相关函数进行角点检测原理 我们前面学习了几个特征检测器,它们大多数效果都很好。但是从实时处理的角度来看,这些算法都不够快。一个最好例子就是 SLAM(同步定位与地图构建),移动机器人,它们的计算资源非常有限。 为了解决这个问题,Edward_Rosten 和 Tom_Drummond 在 2006 年提出里 FAST 算法。我们下面将会对此算法进行一个简单的介绍。你可以参考原始文献获得更多细节(本节中的所有图像都是曲子原始文章)。
34.1 使用 FAST 算法进行特征提取 1. 在图像中选取一个像素点 p,来判断它是不是关键点。I p 等于像素点 p的灰度值。 2. 选择适当的阈值 t。 3. 如下图所示在像素点 p 的周围选择 16 个像素点进行测试。
4. 如果在这 16 个像素点中存在 n 个连续像素点的灰度值都高于 I p + t,或者低于 I p ?t,那么像素点 p 就被认为是一个角点。如上图中的虚线所示,n 选取的值为 12。 5. 为了获得更快的效果,还采用了而外的加速办法。首先对候选点的周围每个 90 度的点:1,9,5,13 进行测试(先测试 1 和 19, 如果它们符合阈值要求再测试 5 和 13)。如果 p 是角点,那么这四个点中至少有 3 个要符合阈值要求。如果不是的话肯定不是角点,就放弃。对通过这步测试的点再继续进行测试(是否有 12 的点符合阈值要求)。这个检测器的效率很高,但是它有如下几条缺点: ? 当 nMIN_MATCH_COUNT: src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2) dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2) M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0) matchesMask = mask.ravel().tolist() h,w = img1.shape pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2) dst = cv2.perspectiveTransform(pts,M) img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3, cv2.LINE_AA) else: print "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT) matchesMask = None # Finally we draw our inliers (if successfully found the object) or matching keypoints (if failed). draw_params = dict(matchColor = (0,255,0), # draw matches in green color singlePointColor = None, matchesMask = matchesMask, # draw only inliers flags = 2) img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params) plt.imshow(img3, 'gray'),plt.show()
结果如下。复杂图像中被找到的目标图像被标记成白色。