一、实践目标
本项目在行空板上外接USB摄像头,通过摄像头来检测目标,并进行跟踪。
二、知识目标
1、学习使用opencv库的feature homography方法来检测目标物并进行跟踪的方法。
三、实践准备
硬件清单:
软件使用:Mind+编程软件x1
四、实践过程
1、硬件搭建
1、将摄像头接入行空板的USB接口。
2、通过USB连接线将行空板连接到计算机。
2、软件编写
第一步:打开Mind+,远程连接行空板
第二步:在“行空板的文件”中新建一个名为AI的文件夹,在其中再新建一个名为“基于行空板的opencv feature_homography目标追踪”的文件夹,导入本节课的依赖文件。
第三步:编写程序
在上述文件的同级目录下新建一个项目文件,并命名为“main.py”。
示例程序:
#!/usr/bin/env python
'''
Feature homography
==================
Example of using features2d framework for interactive video homography matching.
ORB features and FLANN matcher are used. The actual tracking is implemented by
PlaneTracker class in plane_tracker.py
Inspired by http://www.youtube.com/watch?v=-ZNYoL8rzPY
video: http://www.youtube.com/watch?v=FirtmYcC0Vc
Usage
-----
feature_homography.py [<video source>]
Keys:
SPACE - pause video
Select a textured planar object to track by drawing a box with a mouse.
'''
# Python 2/3 compatibility
from __future__ import print_function
# 导入所需库
import numpy as np
import cv2 as cv
# 导入其他模块
import video
from video import presets
import common
from common import getsize, draw_keypoints
from plane_tracker import PlaneTracker
class App:
def __init__(self, src):
# 创建视频捕获对象
self.cap = video.create_capture(src, presets['book'])
self.frame = None
self.paused = False
# 创建平面跟踪器对象
self.tracker = PlaneTracker()
# 创建全屏窗口
cv.namedWindow('plane',cv.WND_PROP_FULLSCREEN)
cv.setWindowProperty('plane', cv.WND_PROP_FULLSCREEN, cv.WINDOW_FULLSCREEN)
# 创建矩形选择器对象,用于用户选择待跟踪的平面区域
self.rect_sel = common.RectSelector('plane', self.on_rect)
def on_rect(self, rect):
# 当用户选择了一个矩形区域后的回调函数
# 清除跟踪器中的所有目标
self.tracker.clear()
# 添加新的跟踪目标
self.tracker.add_target(self.frame, rect)
def run(self):
while True:
# 判断是否需要读取新的视频帧
playing = not self.paused and not self.rect_sel.dragging
if playing or self.frame is None:
# 读取新的视频帧
ret, frame = self.cap.read()
if not ret:
break
self.frame = frame.copy()
# 创建用于显示的图像
w, h = getsize(self.frame)
vis = np.zeros((h*2, w, 3), np.uint8)
vis[:h,:w] = self.frame
# 如果有跟踪目标,显示目标的特征点和矩形框
if len(self.tracker.targets) > 0:
target = self.tracker.targets[0]
vis[h:,:] = target.image
draw_keypoints(vis[h:,:], target.keypoints)
x0, y0, x1, y1 = target.rect
cv.rectangle(vis, (x0, y0+h), (x1, y1+h), (0, 255, 0), 2)
if playing:
# 进行跟踪
tracked = self.tracker.track(self.frame)
if len(tracked) > 0:
# 绘制跟踪结果
tracked = tracked[0]
cv.polylines(vis, [np.int32(tracked.quad)], True, (255, 255, 255), 2)
for (x0, y0), (x1, y1) in zip(np.int32(tracked.p0), np.int32(tracked.p1)):
cv.line(vis, (x0, y0+h), (x1, y1), (0, 255, 0))
# 绘制所有跟踪点
draw_keypoints(vis, self.tracker.frame_points)
# 绘制矩形选择框
self.rect_sel.draw(vis)
# 显示图像
cv.imshow('plane', vis)
ch = cv.waitKey(1)
# 按下空格键暂停/播放
if ch == ord(' '):
self.paused = not self.paused
# 按下ESC键退出
if ch == 27:
break
if __name__ == '__main__':
print(__doc__)
import sys
try:
video_src = sys.argv[1]
except:
video_src = 0
# 运行程序
App(video_src).run()
3. 运行调试
第一步:运行主程序
运行“main.py”程序,可以看到初始时屏幕分为了上下两个区域,上方显示着摄像头拍摄到的实时画面,下方初始时显示黑色背景,之后将摄像头画面对准一个物体(这里为小车),用鼠标将画面中的物体(小车)框出,可以看到框出的小车作为被标记物显示在了下方,轻轻移动小车,可以看到上方的画面中小车始终被框出,并且与下方之间通过光流保持着连接,达到了追踪的目的。
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则是一种稠密光流法。
附件
评论