【OpenCV】85 视频分析—KLT光流跟踪 02

85 视频分析—KLT光流跟踪 02

代码

import numpy as np
import cv2 as cv

cap = cv.VideoCapture('../images/color_object.mp4')

def caldist(a, b, c, d):
    return abs(a-c) + abs(b-d)

def KLTdemo():
    # 角点检测参数
    feature_params = dict(maxCorners=100, qualityLevel=0.01, minDistance=10, blockSize=3)
    # KLT光流参数
    lk_params = dict(winSize=(31, 31), maxLevel=3, criteria=(cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 30, 0.01))
    # 随机颜色
    color = np.random.randint(0,255,(100,3))

    # 读取第一帧
    ret, old_frame = cap.read()
    old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
    p0 = cv.goodFeaturesToTrack(old_gray, mask=None, **feature_params)

    # 光流跟踪
    while True:
        ret, frame = cap.read()
        if ret is False:
            break
        frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
        # 计算光流
        p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
        # 根据状态选择
        good_new = p1[st == 1]
        good_old = p0[st == 1]

        # 删除静止点
        inits = 0
        for i, (new, old) in enumerate(zip(good_new,good_old)):
            a, b = new.ravel()
            c, d = old.ravel()
            distance = caldist(a, b, c, d)
            if distance > 2:
                good_new[inits] = good_new[i]
                good_old[inits] = good_old[i]
                inits += 1
        good_new = good_new[:inits]
        good_old = good_old[:inits]

        # 绘制跟踪线
        for i, (new, old) in enumerate(zip(good_new,good_old)):
            a,b = new.ravel()
            c,d = old.ravel()
            frame = cv.line(frame, (a,b),(c,d), color[i].tolist(), 2)
            frame = cv.circle(frame,(a,b),5,color[i].tolist(),-1)
        cv.imshow('frame',frame)
        k = cv.waitKey(30) & 0xff
        if k == 27:
            break
        # 更新
        old_gray = frame_gray.copy()
        p0 = good_new.reshape(-1, 1, 2)
        if inits < 20:
            p0 = cv.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
    cv.destroyAllWindows()
    cap.release()

if __name__ == '__main__':
    KLTdemo()

实验结果

在这里插入图片描述

解释

光流跟踪方法分为稠密光流跟踪与稀疏光流跟踪算法,KLT是稀疏光流跟踪算法,这个算法最早是由Bruce D. Lucas and Takeo Kanade两位作者提出来的,所以又被称为KLT。稀疏光流算法工作有三个假设前提条件:

  • 亮度恒定
  • 短距离移动
  • 空间一致性

OpenCV中KLT算法API及其参数解释如下:

nextPts, status, err = cv.calcOpticalFlowPyrLK(prevImg, nextImg, prevPts, nextPts[, status[, err[, winSize[, maxLevel[, criteria[, flags[, minEigThreshold]]]]]]])
  • prevImg 前一帧图像
  • nextImg 后一帧图像
  • prevPts 前一帧的稀疏光流点
  • nextPts 后一帧光流点
  • status 输出状态,1 表示正常该点保留,否则丢弃
  • err 表示错误
  • winSize = Size(21, 21) 光流法对象窗口大小
  • maxLevel = 3 金字塔层数,0表示只检测当前图像,不构建金字塔图像
  • criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01) 窗口搜索时候停止条件
  • flags = 0 操作标志
  • minEigThreshold = 1e-4 最小特征值响应,低于最小值不做处理

在84的知识点分享中我们已经可以跟踪到前后两帧之前的位置移动,但是这个还不足够,我们需要绘制移动对象从初始到最终的完整可以检测的运动轨迹,同时对一些静止的角点进行删除,所以我们需要对状态为1的角点,计算它们之间的距离,只有dx+dy > 2(dx=abs(p1.x –p2.x), dy=abs(p1.y-p2.y))的我们才对它进行保留跟踪。


所有内容均来源于贾志刚老师的知识星球——OpenCV研习社,本文为个人整理学习,已获得贾老师授权,有兴趣、有能力的可以加入贾老师的知识星球进行深入学习。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值