一、实践目标
本项目在行空板上外接USB摄像头,通过摄像头来检测目标,并进行跟踪。
二、知识目标
学习使用opencv库的lk homography方法来检测目标物并进行跟踪的方法。
三、实践准备
硬件清单:
四、实践过程
1、硬件搭建 1、将摄像头接入行空板的USB接口。
2、通过USB连接线将行空板连接到计算机。
2、软件编写第一步:打开Mind+,远程连接行空板
第二步:在“行空板的文件”中新建一个名为AI的文件夹,在其中再新建一个名为“基于行空板的opencv lk_homography目标追踪”的文件夹,导入本节课的依赖文件。
第三步:编写程序 在上述文件的同级目录下新建一个项目文件,并命名为“main.py”。 示例程序:
- #!/usr/bin/env python
-
- '''
- Lucas-Kanade homography tracker
- ===============================
- ...
- '''
-
- # Python 2/3 compatibility
- from __future__ import print_function
-
- import numpy as np
- import cv2 as cv
-
- import video
- from common import draw_str
- from video import presets
-
- # 设置Lucas-Kanade光流法的参数
- lk_params = dict( winSize = (19, 19),
- maxLevel = 2,
- criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
-
- # 设置寻找好特征点的参数
- feature_params = dict( maxCorners = 1000,
- qualityLevel = 0.01,
- minDistance = 8,
- blockSize = 19 )
-
- # 定义跟踪函数,通过比较前后两帧的特征点位置,判断是否为有效的跟踪点
- def checkedTrace(img0, img1, p0, back_threshold = 1.0):
- p1, _st, _err = cv.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params)
- p0r, _st, _err = cv.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params)
- d = abs(p0-p0r).reshape(-1, 2).max(-1)
- status = d < back_threshold
- return p1, status
-
- green = (0, 255, 0)
- red = (0, 0, 255)
-
- class App:
- def __init__(self, video_src):
- # 创建视频捕捉对象
- self.cam = self.cam = video.create_capture(video_src, presets['book'])
- self.p0 = None
- self.use_ransac = True
- # 创建一个全屏窗口用于显示
- cv.namedWindow('lk_homography',cv.WND_PROP_FULLSCREEN) #Set the windows to be full screen.
- cv.setWindowProperty('lk_homography', cv.WND_PROP_FULLSCREEN, cv.WINDOW_FULLSCREEN) #Set the windows to be full screen.
-
- def run(self):
- while True:
- # 读取视频帧
- _ret, frame = self.cam.read()
- # 将视频帧转换为灰度图
- frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
- vis = frame.copy()
- if self.p0 is not None:
- # 使用光流法跟踪特征点
- p2, trace_status = checkedTrace(self.gray1, frame_gray, self.p1)
-
- self.p1 = p2[trace_status].copy()
- self.p0 = self.p0[trace_status].copy()
- self.gray1 = frame_gray
-
- if len(self.p0) < 4:
- self.p0 = None
- continue
- # 找到两帧之间的单应性矩阵
- H, status = cv.findHomography(self.p0, self.p1, (0, cv.RANSAC)[self.use_ransac], 10.0)
- h, w = frame.shape[:2]
- overlay = cv.warpPerspective(self.frame0, H, (w, h))
- # 叠加两帧图像
- vis = cv.addWeighted(vis, 0.5, overlay, 0.5, 0.0)
-
- for (x0, y0), (x1, y1), good in zip(self.p0[:,0], self.p1[:,0], status[:,0]):
- if good:
- cv.line(vis, (int(x0), int(y0)), (int(x1), int(y1)), (0, 128, 0))
- cv.circle(vis, (int(x1), int(y1)), 2, (red, green)[good], -1)
- draw_str(vis, (20, 20), 'track count: %d' % len(self.p1))
- if self.use_ransac:
- draw_str(vis, (20, 40), 'RANSAC')
- else:
- p = cv.goodFeaturesToTrack(frame_gray, **feature_params)
- if p is not None:
- for x, y in p[:,0]:
- cv.circle(vis, (int(x), int(y)), 2, green, -1)
- draw_str(vis, (20, 20), 'feature count: %d' % len(p))
-
- cv.imshow('lk_homography', vis)
-
- ch = cv.waitKey(1)
- if ch == 27:
- break
- if ch == ord('a'):
- self.frame0 = frame.copy()
- self.p0 = cv.goodFeaturesToTrack(frame_gray, **feature_params)
- if self.p0 is not None:
- self.p1 = self.p0
- self.gray0 = frame_gray
- self.gray1 = frame_gray
- if ch == ord('b'):
- self.use_ransac = not self.use_ransac
-
- def main():
- import sys
- try:
- video_src = sys.argv[1]
- except:
- video_src = 0
-
- # 运行应用程序
- App(video_src).run()
- print('Done')
-
- if __name__ == '__main__':
- print(__doc__)
- main()
- cv.destroyAllWindows()
复制代码
3、运行调试第一步:运行主程序 运行“main.py”程序,将Mind+放入画面中,Mind+随即被检测出并以绿色光点标记,轻轻移动后,依旧在画面中,同时,可以在屏幕上方看到标记特征点的数量。
4、程序解析在上述的“main.py”文件中,我们主要通过opencv库来调用摄像头,获取实时视频流,然后借助计算机视觉中的lk homography算法来实现实时跟踪视频中的特征点,并在视频帧上画出这些特征点的运动轨迹,整体流程如下,
①初始化:程序启动时,会创建一个App类的实例,打开视频源,创建一个全屏窗口用于显示。
②主循环:程序进入一个无限循环,每次循环都会读取一帧视频,然后进行以下处理: 如果已经找到了初始特征点(即self.p0不为None),那么程序会使用Lucas-Kanade光流法跟踪这些特征点在当前帧中的位置,然后根据前后两帧特征点的位置找到单应性矩阵,然后用这个矩阵将初始帧映射到当前帧,形成一个叠加图像。 如果还没有找到初始特征点,那么程序会在当前帧中寻找好的特征点,并标记出来。
③用户交互:程序会检查用户的键盘输入,如果按下'a'键,那么程序会在当前帧中寻找好的特征点,作为初始特征点;如果按下'b'键,那么程序会切换是否使用RANSAC算法来计算单应性矩阵;如果按下'ESC'键,那么程序会退出。
④结束:当主循环结束时,程序会关闭所有的窗口,然后退出。 这个程序的主要目标是跟踪视频中的特征点,并通过找到前后两帧之间的单应性,实现对场景的稳定。这是通过在每一帧中跟踪特征点,然后使用这些特征点来计算单应性矩阵,然后用这个矩阵将初始帧映射到当前帧,形成叠加图像来实现的。
五、知识园地
1. 了解lk homography"Lucas-Kanade" (LK) 和 "Homography" 是两个分别代表不同概念的术语,但在计算机视觉和图像处理中,它们常常被联合使用以实现特定的功能。
Lucas-Kanade (LK): Lucas-Kanade (LK) 是一种光流估计算法。光流是空间运动物体在观察成像平面上的像素变化,它可以描述图像序列中的运动对象的运动。Lucas-Kanade方法是基于对局部像素窗口进行最小二乘拟合的方法。LK算法假设窗口内的所有像素都有相同的运动。在实际应用中,LK算法常常被用来跟踪视频中的特征点。
Homography: Homography 是一个变换,它描述了两个平面之间的映射关系。在计算机视觉中,Homography常常被用于图像配准和透视变换等任务。对于两幅图像,如果我们知道它们之间的特征点对应关系,就可以计算出这两幅图像之间的Homography,然后用这个Homography把一幅图像映射到另一幅图像上。 当我们谈论 "LK Homography" 时,通常是指结合使用LK算法和Homography来实现某种功能,比如特征点跟踪和图像配准。具体来说,可以先用LK算法在视频序列中跟踪特征点,然后用这些特征点计算出前后帧之间的Homography,最后用这个Homography实现图像的配准或叠加。
|