17267浏览
查看: 17267|回复: 0

[教程] 基于行空板的opencv feature_homography目标追踪

[复制链接]
一、实践目标

本项目在行空板上外接USB摄像头,通过摄像头来检测目标,并进行跟踪。

二、知识目标

1、学习使用opencv库的feature homography方法来检测目标物并进行跟踪的方法。

三、实践准备

硬件清单:

基于行空板的opencv feature_homography目标追踪图3

软件使用:Mind+编程软件x1

四、实践过程

1、硬件搭建
1、将摄像头接入行空板的USB接口。

基于行空板的opencv feature_homography目标追踪图2

2、通过USB连接线将行空板连接到计算机。

基于行空板的opencv feature_homography目标追踪图1

2、软件编写
第一步:打开Mind+,远程连接行空板

基于行空板的opencv feature_homography目标追踪图5

第二步:在“行空板的文件”中新建一个名为AI的文件夹,在其中再新建一个名为“基于行空板的opencv feature_homography目标追踪”的文件夹,导入本节课的依赖文件。

基于行空板的opencv feature_homography目标追踪图4

第三步:编写程序
在上述文件的同级目录下新建一个项目文件,并命名为“main.py”。
示例程序:
  1. #!/usr/bin/env python
  2. '''
  3. Feature homography
  4. ==================
  5. Example of using features2d framework for interactive video homography matching.
  6. ORB features and FLANN matcher are used. The actual tracking is implemented by
  7. PlaneTracker class in plane_tracker.py
  8. Inspired by http://www.youtube.com/watch?v=-ZNYoL8rzPY
  9. video: http://www.youtube.com/watch?v=FirtmYcC0Vc
  10. Usage
  11. -----
  12. feature_homography.py [<video source>]
  13. Keys:
  14.    SPACE  -  pause video
  15. Select a textured planar object to track by drawing a box with a mouse.
  16. '''
  17. # Python 2/3 compatibility
  18. from __future__ import print_function
  19. # 导入所需库
  20. import numpy as np
  21. import cv2 as cv
  22. # 导入其他模块
  23. import video
  24. from video import presets
  25. import common
  26. from common import getsize, draw_keypoints
  27. from plane_tracker import PlaneTracker
  28. class App:
  29.     def __init__(self, src):
  30.         # 创建视频捕获对象
  31.         self.cap = video.create_capture(src, presets['book'])
  32.         self.frame = None
  33.         self.paused = False
  34.         # 创建平面跟踪器对象
  35.         self.tracker = PlaneTracker()
  36.         # 创建全屏窗口
  37.         cv.namedWindow('plane',cv.WND_PROP_FULLSCREEN)
  38.         cv.setWindowProperty('plane', cv.WND_PROP_FULLSCREEN, cv.WINDOW_FULLSCREEN)
  39.         # 创建矩形选择器对象,用于用户选择待跟踪的平面区域
  40.         self.rect_sel = common.RectSelector('plane', self.on_rect)
  41.     def on_rect(self, rect):
  42.         # 当用户选择了一个矩形区域后的回调函数
  43.         # 清除跟踪器中的所有目标
  44.         self.tracker.clear()
  45.         # 添加新的跟踪目标
  46.         self.tracker.add_target(self.frame, rect)
  47.     def run(self):
  48.         while True:
  49.             # 判断是否需要读取新的视频帧
  50.             playing = not self.paused and not self.rect_sel.dragging
  51.             if playing or self.frame is None:
  52.                 # 读取新的视频帧
  53.                 ret, frame = self.cap.read()
  54.                 if not ret:
  55.                     break
  56.                 self.frame = frame.copy()
  57.             # 创建用于显示的图像
  58.             w, h = getsize(self.frame)
  59.             vis = np.zeros((h*2, w, 3), np.uint8)
  60.             vis[:h,:w] = self.frame
  61.             # 如果有跟踪目标,显示目标的特征点和矩形框
  62.             if len(self.tracker.targets) > 0:
  63.                 target = self.tracker.targets[0]
  64.                 vis[h:,:] = target.image
  65.                 draw_keypoints(vis[h:,:], target.keypoints)
  66.                 x0, y0, x1, y1 = target.rect
  67.                 cv.rectangle(vis, (x0, y0+h), (x1, y1+h), (0, 255, 0), 2)
  68.             if playing:
  69.                 # 进行跟踪
  70.                 tracked = self.tracker.track(self.frame)
  71.                 if len(tracked) > 0:
  72.                     # 绘制跟踪结果
  73.                     tracked = tracked[0]
  74.                     cv.polylines(vis, [np.int32(tracked.quad)], True, (255, 255, 255), 2)
  75.                     for (x0, y0), (x1, y1) in zip(np.int32(tracked.p0), np.int32(tracked.p1)):
  76.                         cv.line(vis, (x0, y0+h), (x1, y1), (0, 255, 0))
  77.             # 绘制所有跟踪点
  78.             draw_keypoints(vis, self.tracker.frame_points)
  79.             # 绘制矩形选择框
  80.             self.rect_sel.draw(vis)
  81.             # 显示图像
  82.             cv.imshow('plane', vis)
  83.             ch = cv.waitKey(1)
  84.             # 按下空格键暂停/播放
  85.             if ch == ord(' '):
  86.                 self.paused = not self.paused
  87.             # 按下ESC键退出
  88.             if ch == 27:
  89.                 break
  90. if __name__ == '__main__':
  91.     print(__doc__)
  92.     import sys
  93.     try:
  94.         video_src = sys.argv[1]
  95.     except:
  96.         video_src = 0
  97.     # 运行程序
  98.     App(video_src).run()
复制代码

3. 运行调试
第一步:运行主程序
运行“main.py”程序,可以看到初始时屏幕分为了上下两个区域,上方显示着摄像头拍摄到的实时画面,下方初始时显示黑色背景,之后将摄像头画面对准一个物体(这里为小车),用鼠标将画面中的物体(小车)框出,可以看到框出的小车作为被标记物显示在了下方,轻轻移动小车,可以看到上方的画面中小车始终被框出,并且与下方之间通过光流保持着连接,达到了追踪的目的。

基于行空板的opencv feature_homography目标追踪图6

4、程序解析
在上述的“main.py”文件中,我们主要通过opencv库来调用摄像头,获取实时视频流,然后借助计算机视觉中的ORB特征和FLANN匹配器来实现对视频中特定平面的跟踪。用户可以通过鼠标在视频中选择一个区域,然后程序会在之后的视频帧中跟踪这个区域的位置和姿态。整体流程如下,
①初始化视频源和跟踪器:程序首先打开视频源,并创建一个PlaneTracker对象用于跟踪。
②用户选择跟踪区域:用户通过鼠标在视频中选择一个区域,选择的区域将被添加到PlaneTracker中作为跟踪目标。
③跟踪处理:程序会逐帧读取视频,并将每一帧传递给PlaneTracker进行处理。PlaneTracker会使用ORB特征和FLANN匹配器找到当前帧中与目标相匹配的特征,并计算出目标在当前帧中的位置和姿态。
④显示结果:程序会将跟踪的结果(包括目标的位置和姿态)实时地显示在视频上。如果跟踪成功,目标区域会被高亮显示。
⑤用户交互:用户可以通过按下空格键来暂停或继续视频的播放。如果用户在视频暂停时选择了新的区域,这个区域将会替换原来的跟踪目标。

五、知识园地
1. 了解ORB特征(Oriented FAST and Rotated BRIEF)
ORB特征,全称为Oriented FAST and Rotated BRIEF,是一种高效的特征检测和描述算法,由Ethan Rublee等人在2011年的论文"ORB: An efficient alternative to SIFT or SURF"中提出。
ORB特征算法主要包含两个部分:特征点检测和特征描述。
1、特征点检测:ORB使用了FAST角点检测器进行特征点的检测。FAST角点检测器是一种高效的角点检测算法,可以快速地在图像中找到角点。然而,FAST角点检测器检测到的角点没有方向信息,为了解决这个问题,ORB算法引入了角点的方向信息,从而得到了带有方向信息的特征点。
2、特征描述:ORB使用了rBRIEF描述子进行特征描述。BRIEF是一种二进制的特征描述符,它通过比较图像中一个小区域内的像素对的亮度,生成一串二进制串作为该区域的描述子。然而,BRIEF描述子不具有旋转不变性,即当图像旋转时,BRIEF描述子会发生变化。ORB通过在BRIEF的基础上引入了旋转不变性,得到了rBRIEF描述子。
ORB特征算法的主要优点是计算速度快,内存占用少,适合于实时应用和嵌入式设备。它的性能与SIFT和SURF等算法相当,但计算速度更快,内存占用更少。

2. 了解FLANN匹配器(Fast Library for Approximate Nearest Neighbors)
FLANN(Fast Library for Approximate Nearest Neighbors)是一个用于进行大规模数据集中的快速近邻搜索的库。在很多计算机视觉和机器学习的任务中,我们经常需要在高维空间中找到某个点的最近邻点,这是一个在计算上非常昂贵的任务。FLANN库提供了一种快速和高效的方法来进行这个操作。
FLANN支持多种类型的数据和距离度量,包括欧几里得距离、曼哈顿距离、汉明距离等,并且可以自动选择最适合你数据的算法。它提供了一种称为索引的数据结构,可以将数据预处理成特定的格式,以便在搜索时更快地找到最近邻。
在计算机视觉中,FLANN常常被用来进行特征匹配。比如说,我们在两张图片中分别提取出了一些特征点,然后需要找出在两张图片中对应的特征点。这时候,我们就可以使用FLANN来快速找到每个特征点的最近邻,从而实现特征匹配。
在OpenCV中,FLANN匹配器可以通过cv2.FlannBasedMatcher类来使用。这个类提供了knnMatch和radiusMatch等方法,可以进行k-近邻匹配和半径匹配。

3. 了解光流法(Optical Flow)
光流(Optical Flow)是计算机视觉中的一种重要技术,它主要用于从视频序列中估计物体的运动。光流描述的是图像序列中的像素在时间维度上的运动变化,即每个像素点随时间在图像平面上的移动轨迹。
光流的基本假设是图像的亮度在短时间内是恒定不变的,即一个像素点在当前帧和下一帧中的亮度是相同的。另外,光流还假设相邻像素具有相似的运动,即物体的运动是连续的。
光流法通常用于估计视频中物体的速度或者运动方向。例如,在自动驾驶、视频监控、运动检测等领域,光流法都有广泛的应用。
在计算方法上,光流法主要有两类:稀疏光流法和稠密光流法。稀疏光流法只在一些特定的点(例如特征点)上计算光流,而稠密光流法则在每个像素点上都计算光流。
在OpenCV中,有函数cv2.calcOpticalFlowPyrLK和cv2.calcOpticalFlowFarneback等可以用于计算光流。其中,cv2.calcOpticalFlowPyrLK是一种基于Lucas-Kanade方法的稀疏光流法,而cv2.calcOpticalFlowFarneback则是一种稠密光流法。

project.zip

10.51 KB, 下载次数: 1

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail