一、实践目标
本项目在行空板上外接USB摄像头,通过摄像头来检测目标,并进行跟踪。
二、知识目标
1、学习使用opencv库的lk homography方法来检测目标物并进行跟踪的方法。
三、实践准备
硬件清单:
![截屏2024-06-05 下午2.07.06.png](https://makelogimg.dfrobot.com.cn/makelog/652ce4c9f6f6eea679b51bc3/4ca27bf73492fc6db256943b3168c1f1.png)
软件使用:Mind+编程软件x1
四、实践过程
1、硬件搭建
1、将摄像头接入行空板的USB接口。
![image.png](https://makelogimg.dfrobot.com.cn/makelog/652ce4c9f6f6eea679b51bc3/e4df6d62aa0703ec0a2409abc5e0309f.png)
2、通过USB连接线将行空板连接到计算机。
![image.png](https://makelogimg.dfrobot.com.cn/makelog/652ce4c9f6f6eea679b51bc3/d93a27bab83b86d2e6481148dd97d939.png)
2、软件编写
第一步:打开Mind+,远程连接行空板
![image.png](https://makelogimg.dfrobot.com.cn/makelog/652ce4c9f6f6eea679b51bc3/bdb9dc1c32fdc1daeb744b3e9e8b9579.png)
第二步:在“行空板的文件”中新建一个名为AI的文件夹,在其中再新建一个名为“基于行空板的opencv lk_homography目标追踪”的文件夹,导入本节课的依赖文件。
![image.png](https://makelogimg.dfrobot.com.cn/makelog/652ce4c9f6f6eea679b51bc3/201149aaef17481ec23dd20a19603c43.png)
第三步:编写程序
在上述文件的同级目录下新建一个项目文件,并命名为“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+随即被检测出并以绿色光点标记,轻轻移动后,依旧在画面中,同时,可以在屏幕上方看到标记特征点的数量。
![image.png](https://makelogimg.dfrobot.com.cn/makelog/652ce4c9f6f6eea679b51bc3/0650464d396b55e51a8c389ad44e492e.png)
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实现图像的配准或叠加。
附件
评论