文章目录
1.原理
- 由于目标对象或者摄像机的移动,造成的图像对象在连续两帧图像中的移动被称为光流。它是一个2D 向量场,可以用来显示一个点从第一帧图像到第二帧图像之间的移动。
上图显示了一个点在连续的五帧图像间的移动。箭头表示光流场向量。光流在很多领域中都很有用: 运动重建结构、视频压缩、Video Stabilization 等。 - 光流是基于以下假设的:1. 在连续的两帧图像之间(目标对象的)像素的灰度值不改变。2. 相邻的像素具有相同的运动。
2.Lucas-Kanade 法
- 利用一个3x3 邻域中的9 个点具有相同运动的这一点,找到这9 个点的光流方程,用它们组成一个具有两个未知数9 个等式的方程组。
- 从使用者的角度来看,我们去跟踪一些点,然后就会获得这些点的光流向量。但我们处理的都是很小的运动。如果有大的运动怎么办呢?我们可以使用图像金字塔的顶层。此时小的运动被移除,大的运动装换成了小的运动,再使用Lucas-Kanade算法,我们就会得到尺度空间上的光流。
代码速记:
- cv2.goodFeaturesToTrack()
- cv2.calcOpticalFlowPyrLK()
实战:
def lucas(self):
cap = cv2.VideoCapture('../images/slow.flv')
#ShiTomasi角点检测所需参数
feature_params = dict(maxCorners=100,
qualityLevel=0.3,
minDistance=7,
blockSize=7)
#lucas kanade光流所需参数
# maxLevel 为使用的图像金字塔层数
lk_params = dict(winSize=(15, 15),
maxLevel=2,
criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
#随机颜色
color = np.random.randint(0, 255, (100, 3))
#【1】读取第一帧,并进行角点检测,确定要跟踪的点
ret, old_frame = cap.read