光流估计
光流是一种运动模式,这种运动模式指的是一个物体、表面、边缘在一个视角下由一个观察者(比如眼睛、摄像头等)和背景之间形成的明显移动
Lucas–Kanade光流算法是一种两帧差分的光流估计算法
算法实现:Lucas-Kanade 算法
eg: p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params
调用OpenCV中的函数cv2.calcOpticalFlowPyrLK():
参数:
-
prevImage 前一帧图像
-
nextImage 当前帧图像
-
prevPts 待跟踪的特征点向量
-
winSize 搜索窗口的大小
-
maxLevel 最大的金字塔层数
返回:
-
nextPts 输出跟踪特征点向量
-
status 特征点是否找到,找到的状态为1,未找到的状态为0
代码
import cv2
import numpy as np
cap=cv2.VideoCapture(‘test.avi’)#转换帧
#角点检测所需参数
feature_params=dict(
maxCorners=100, #最大角点数
qualityLevel = 0.3,#角点最低质量
minDistance=7)#角点间最小欧氏距离
#lincas_canada参数
lk_params=dict(
winSize=(15,15), #搜索串口大小
maxLevel=2) #最大的金字塔层数
#随机颜色条
color=np.random.randint=(0,255,(100,3))
#拿到第一帧图像
ret,old_frame=cap.read()
old_gray=cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)
#cv2.goodFeaturesToTrack()函数是用来跟踪检测图像中的角点
p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
#创建一个mask
mask=np.zeros_like(old_frame)
while(True):
ret,frame=cap.read()
frame_gray=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
# 需要传入前一帧和当前图像以及前一帧检测到的角点
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
#st=1表示找到特征点
good_news=p1[st1]
good_old=p0[st1]
#绘制轨迹
for i,(new,old) in enumerate(zip(good_news,good_old)):
a,b=new.ravel() #变成一维
c,d=old.ravel()
mask = cv2.line(mask, (a, b), (c, d), (0,0,255), 2)
frame = cv2.circle(frame, (a, b), 5, (0,0,255), -1)
img=cv2.add(frame,mask)
cv2.imshow(‘img’,img)
k=cv2.waitKey(150) & 0xff
if k==27:
break
#更新
old_gray=frame_gray.copy()
p0=good_news.reshape(-1,1,2)
cap.release()
cv2.destroyAllWindows()