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

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

[复制链接]
一、实践目标
本项目在行空板上外接USB摄像头,通过摄像头来检测目标,并进行跟踪。

二、知识目标
学习使用opencv库的lk homography方法来检测目标物并进行跟踪的方法。

三、实践准备
硬件清单:

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

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

四、实践过程
1、硬件搭建
1、将摄像头接入行空板的USB接口。

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

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

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

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

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

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

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

第三步:编写程序
在上述文件的同级目录下新建一个项目文件,并命名为“main.py”。
示例程序:
  1. #!/usr/bin/env python
  2. '''
  3. Lucas-Kanade homography tracker
  4. ===============================
  5. ...
  6. '''
  7. # Python 2/3 compatibility
  8. from __future__ import print_function
  9. import numpy as np
  10. import cv2 as cv
  11. import video
  12. from common import draw_str
  13. from video import presets
  14. # 设置Lucas-Kanade光流法的参数
  15. lk_params = dict( winSize  = (19, 19),
  16.                   maxLevel = 2,
  17.                   criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
  18. # 设置寻找好特征点的参数
  19. feature_params = dict( maxCorners = 1000,
  20.                        qualityLevel = 0.01,
  21.                        minDistance = 8,
  22.                        blockSize = 19 )
  23. # 定义跟踪函数,通过比较前后两帧的特征点位置,判断是否为有效的跟踪点
  24. def checkedTrace(img0, img1, p0, back_threshold = 1.0):
  25.     p1, _st, _err = cv.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params)
  26.     p0r, _st, _err = cv.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params)
  27.     d = abs(p0-p0r).reshape(-1, 2).max(-1)
  28.     status = d < back_threshold
  29.     return p1, status
  30. green = (0, 255, 0)
  31. red = (0, 0, 255)
  32. class App:
  33.     def __init__(self, video_src):
  34.         # 创建视频捕捉对象
  35.         self.cam = self.cam = video.create_capture(video_src, presets['book'])
  36.         self.p0 = None
  37.         self.use_ransac = True
  38.         # 创建一个全屏窗口用于显示
  39.         cv.namedWindow('lk_homography',cv.WND_PROP_FULLSCREEN)    #Set the windows to be full screen.
  40.         cv.setWindowProperty('lk_homography', cv.WND_PROP_FULLSCREEN, cv.WINDOW_FULLSCREEN)    #Set the windows to be full screen.
  41.     def run(self):
  42.         while True:
  43.             # 读取视频帧
  44.             _ret, frame = self.cam.read()
  45.             # 将视频帧转换为灰度图
  46.             frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
  47.             vis = frame.copy()
  48.             if self.p0 is not None:
  49.                 # 使用光流法跟踪特征点
  50.                 p2, trace_status = checkedTrace(self.gray1, frame_gray, self.p1)
  51.                 self.p1 = p2[trace_status].copy()
  52.                 self.p0 = self.p0[trace_status].copy()
  53.                 self.gray1 = frame_gray
  54.                 if len(self.p0) < 4:
  55.                     self.p0 = None
  56.                     continue
  57.                 # 找到两帧之间的单应性矩阵
  58.                 H, status = cv.findHomography(self.p0, self.p1, (0, cv.RANSAC)[self.use_ransac], 10.0)
  59.                 h, w = frame.shape[:2]
  60.                 overlay = cv.warpPerspective(self.frame0, H, (w, h))
  61.                 # 叠加两帧图像
  62.                 vis = cv.addWeighted(vis, 0.5, overlay, 0.5, 0.0)
  63.                 for (x0, y0), (x1, y1), good in zip(self.p0[:,0], self.p1[:,0], status[:,0]):
  64.                     if good:
  65.                         cv.line(vis, (int(x0), int(y0)), (int(x1), int(y1)), (0, 128, 0))
  66.                     cv.circle(vis, (int(x1), int(y1)), 2, (red, green)[good], -1)
  67.                 draw_str(vis, (20, 20), 'track count: %d' % len(self.p1))
  68.                 if self.use_ransac:
  69.                     draw_str(vis, (20, 40), 'RANSAC')
  70.             else:
  71.                 p = cv.goodFeaturesToTrack(frame_gray, **feature_params)
  72.                 if p is not None:
  73.                     for x, y in p[:,0]:
  74.                         cv.circle(vis, (int(x), int(y)), 2, green, -1)
  75.                     draw_str(vis, (20, 20), 'feature count: %d' % len(p))
  76.             cv.imshow('lk_homography', vis)
  77.             ch = cv.waitKey(1)
  78.             if ch == 27:
  79.                 break
  80.             if ch == ord('a'):
  81.                 self.frame0 = frame.copy()
  82.                 self.p0 = cv.goodFeaturesToTrack(frame_gray, **feature_params)
  83.                 if self.p0 is not None:
  84.                     self.p1 = self.p0
  85.                     self.gray0 = frame_gray
  86.                     self.gray1 = frame_gray
  87.             if ch == ord('b'):
  88.                 self.use_ransac = not self.use_ransac
  89. def main():
  90.     import sys
  91.     try:
  92.         video_src = sys.argv[1]
  93.     except:
  94.         video_src = 0
  95.     # 运行应用程序
  96.     App(video_src).run()
  97.     print('Done')
  98. if __name__ == '__main__':
  99.     print(__doc__)
  100.     main()
  101.     cv.destroyAllWindows()
复制代码

3、运行调试
第一步:运行主程序
运行“main.py”程序,将Mind+放入画面中,Mind+随即被检测出并以绿色光点标记,轻轻移动后,依旧在画面中,同时,可以在屏幕上方看到标记特征点的数量。

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

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实现图像的配准或叠加。


Project.zip

8.31 KB, 下载次数: 85

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

本版积分规则

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

硬件清单

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

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

mail