OpenCV学习笔记-光流

一、光流
由于目标对象或者摄像机的移动造成的图像对象在连续两帧图像中的移动被称为光流。它是一个2D向量场,可以用来显示一个点从第一帧图像到第二帧图像的移动。

光流是基于以下假设的:

1、在连续的两帧图像之间(目标对象的)像素的灰度值不改变
2、相邻的像素具有相同的运动

具体数学原理参考:https://blog.csdn.net/sophia_tone2w/article/details/51166946,《学习OpenCV》讲解很清楚
二、Lucas-Kanade法:

三、OpenCV中的Lucas-kanade光流

我们使用cv.goodFeatureToTrack()函数在视频的第一帧图像中检测一些Shi-Tomasi角点,然后我们使用Lucas-kanade算大迭代跟踪这些角点。我们给函数cv.calcOpticlaFlowPyrLK()传入前一帧图像和其中的点,以及下一帧图像,函数将会返回带有状态数的点,如果状态数是1.那说明在下一帧图像中找到了这个点(上一帧的角点),我们再把这些点作为参数传给函数,如此迭代下去实现跟踪。
我们还要对返回角点的正确性进行检查。图像中的一些特征点甚至在丢失后,光流还会找到一个预期相似的点。所以为了实现稳定的跟踪,我们应该每隔一定间隔就要进行一次角点检测。
具体代码:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

cap = cv.VideoCapture('img/slow.flv')

#查找shi-tomasi角点需要的参数
feature_params = dict(maxCorners = 100, #  最大角点数
                      qualityLevel = 0.3,   # 角点的质量阈值
                      minDistance = 7,  # 相邻角点间最小距离
                      blockSize = 5) #  邻域大小
#调用Lucas kanade函数需要的参数
lk_params = dict(winSize = (15, 15),    # 邻域大小
                 maxLevel = 2,  # 图像金字塔层数
                 criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03)) # 迭代终止条件

#设置随机颜色
color = np.random.randint(0, 255, (100, 3))

ret, old_frame = cap.read()
old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
#找到角点
Pt0 = cv.goodFeaturesToTrack(old_gray, mask= None, **feature_params)

#创建一个掩模
mask = np.zeros_like(old_frame)

while True:
    ret, frame = cap.read()
    frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    #执行calcOpticalFlowPyrLK函数,返回新的角点,角点状态
    Pt1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, Pt0, None, **lk_params)

    #选择找到的角点
    good_new = Pt1[st == 1]
    good_old = Pt0[st == 1]

    #画框
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        a, b = new.ravel()
        c, d = old.ravel()
        mask = cv.line(mask, (a, b), (c, d), color[i].tolist(), 2)
        frame = cv.circle(frame, (a, b), 5, color[i].tolist(), -1)

    img = cv.add(frame, mask)
    cv.imshow('img', img)
    k = cv.waitKey(60) & 0xff
    if k == 27:
        break

    #更新参数,继续迭代
    old_gray = frame_gray.copy()
    Pt0 = good_new.reshape(-1, 1, 2)


cv.destroyAllWindows()
cap.release()

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值