【OpenCV】计算视频的光流并跟踪物体calcOpticalFlowPyrLK

这篇具有很好参考价值的文章主要介绍了【OpenCV】计算视频的光流并跟踪物体calcOpticalFlowPyrLK。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 一、介绍

        计算光流可以使用OpenCV的calcOpticalFlowPyrLK方法,cv2.calcOpticalFlowPyrLK是OpenCV库中的一个函数,用于计算稀疏光流。它实现的是Lucas-Kanade方法,这是一种常用的光流计算方法。

        光流是图像中物体运动的近似表示,它描述了图像中每个像素点在连续两帧之间的移动。Lucas-Kanade方法假设图像中的一个小邻域内的所有像素在运动上是一致的(即具有相同的光流)。

二、原理

        以下是cv2.calcOpticalFlowPyrLK的基本工作原理:

        1. 选择特征点:在第一帧图像中选择一些特征点。这些特征点通常是角点,因为角点具有在所有方向上的变化,更容易被跟踪。

        2. 窗口:对于每一个特征点,定义一个周围的窗口。

        3. 光流:对于每一个窗口,假设所有像素具有相同的光流,然后通过最小化该窗口内像素在第一帧和第二帧之间的亮度差异,来求解光流。

        4. 金字塔:实际上,由于运动可能在不同的尺度上发生,所以cv2.calcOpticalFlowPyrLK实际上在图像的多个尺度(金字塔的每一层)上重复以上步骤。这就是所谓的金字塔Lucas-Kanade方法。

        需要注意的是,由于Lucas-Kanade方法假设一个窗口内的所有像素具有相同的光流,所以它只能处理小的和平滑的运动。对于大的或复杂的运动,需要使用更复杂的方法,如Horn-Schunck方法 

三、代码实现

        下面这段代码实现了识别特征点,并跟踪这些特征点,画出每个点的移动轨迹

import numpy as np
import cv2

src_path = r'input.mp4'
target_path = r'output.mp4'

fps = 25
cap = cv2.VideoCapture(src_path)

# ShiTomasi corner detection的参数
feature_params = dict(maxCorners=300,
                      qualityLevel=0.3,
                      minDistance=7,
                      blockSize=7)
# 光流法参数
# maxLevel 未使用的图像金字塔层数
lk_params = dict(winSize=(10, 10),
                 maxLevel=2,
                 criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))

ret, old_frame = cap.read()                             # 取出视频的第一帧
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)  # 灰度化
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
mask = np.zeros_like(old_frame)                         # 为绘制创建掩码图片
h, w, _ = old_frame.shape
target_video = cv2.VideoWriter(target_path,cv2.VideoWriter_fourcc(*"H264"), fps, (w, h))
while True:
    res, frame = cap.read()
    if not res:
        break
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    # 计算光流以获取点的新位置
    p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
    # 选择good points
    good_new = p1[st == 1]
    good_old = p0[st == 1]
    good_new1 = good_new.copy()
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        a, b = new.ravel()
        c, d = old.ravel()
        mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), (0,255,0), 3)
        frame = cv2.circle(frame, (int(a), int(b)), 5, (0,255,0), -1)
    img = cv2.add(frame, mask)
    target_video.write(img)
    old_gray = frame_gray.copy()
    p0 = good_new1.reshape(-1, 1, 2)

target_video.release()
cv2.destroyAllWindows()
cap.release()

四、参数解释

1.calcOpticalFlowPyrLK输入参数解释

1. prevImg:上一帧输入图像。

2. nextImg:本轮输入图像。

3. prevPts:从上一帧图像中提取的特征点(2D点向量)。

4. nextPts:从本轮图像中提取的点(2D点向量),包含计算得到的新位置。

5. winSize:每一级金字塔的搜索窗口大小。默认值是Size(21,21)。

        图像金字塔是通过对原始图像进行连续的下采样操作得到的一系列图像,每一层的图像都比上一层的图像小。这就像一个金字塔,底部是原始的大图像,顶部是最小的图像。图像金字塔被用于处理不同尺度的运动。这是因为在实际的图像中,物体的运动可能在不同的尺度上发生。例如,远离摄像头的物体在图像中的运动可能比较小,而靠近摄像头的物体在图像中的运动可能比较大。通过在图像金字塔的每一层上计算光流,可以处理这种不同尺度的运动。

6. maxLevel:基于0的最大金字塔等级数;如果设置为0,则不使用金字塔(单级),如果设置为1,则使用两级等。默认值是3。

        在构建图像金字塔时,从原始图像开始,每一层图像的尺寸都是上一层图像尺寸的一半,maxLevel就是这个金字塔的最大层数。maxLevel=0表示只使用原始图像,maxLevel=1表示原始图像和它的一半尺寸的图像,maxLevel=2表示原始图像、一半尺寸的图像和四分之一尺寸的图像,以此类推。

7. criteria:criteria是一个重要的参数,需要详细说一下,该参数是一个指定迭代搜索算法的终止准则的元组。它包含三个元素:
        (1) cv2.TERM_CRITERIA_EPS 或 cv2.TERM_CRITERIA_COUNT 或两者的组合。这些是终止准则的类型:
- cv2.TERM_CRITERIA_EPS:达到指定的精度epsilon时,迭代就会停止。
- cv2.TERM_CRITERIA_COUNT:达到指定的最大迭代次数时,迭代就会停止。
- cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT:当任一上述条件满足时,迭代就会停止。
        (2) 最大迭代次数。在这个例子中,最大迭代次数是10。
        (3)epsilon,即所需的精度。在这个例子中,epsilon是0.03。
例如,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)意味着迭代将在达到10次迭代或误差精度达到0.03时停止,以先到达的条件为准 

8. flags:操作标志。可以设置为

        (1)0:没有特殊行为。

        (2)cv2.OPTFLOW_USE_INITIAL_FLOW:如果设置了这个标志,那么函数会使用nextPts参数中的点作为初始近似值,然后进行优化。否则,它会直接使用prevPts参数中的点作为初始值。
         (3)cv2.OPTFLOW_LK_GET_MIN_EIGENVALS:如果设置了这个标志,那么函数会计算每个点的最小特征值并将它们存储在err参数中。

        0,cv2.OPTFLOW_USE_INITIAL_FLOW或cv2.OPTFLOW_LK_GET_MIN_EIGENVALS。

        例如,如果你想使用nextPts中的点作为初始近似值,你可以这样调用函数:

p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, flags=cv2.OPTFLOW_USE_INITIAL_FLOW, **lk_params)

9. minEigThreshold:最小特征值的阈值。默认值是1e-4。

这个函数的主要目的是使用Lucas-Kanade方法在两个图像之间跟踪一些特征点(prevPts)。这些特征点的新位置被存储在nextPts中。如果一个点不能被跟踪(例如,因为它走出了图像),那么status向量的相应元素就会被设置为0 

2.calcOpticalFlowPyrLK输出参数解释

1. nextPts:这是一个数组,包含了在下一帧图像中找到的输入特征点的新位置。

2. status:这是一个数组,和输入的特征点数组大小相同。如果status[i]为1,表示找到了第i个特征点的新位置,如果为0,表示没有找到。

3. err:这是一个数组,和输入的特征点数组大小相同。err[i]表示第i个特征点的新位置和原位置之间的误差,这个误差是基于窗口大小的。

这三个输出参数可以用于理解和评估光流的计算结果。例如,你可以检查status数组来看哪些特征点在下一帧图像中被成功找到,或者查看err数组来评估光流的计算精度 

        calcOpticalFlowPyrLK的用法就简单介绍到这,关注不迷路(#^.^#)文章来源地址https://www.toymoban.com/news/detail-782197.html

到了这里,关于【OpenCV】计算视频的光流并跟踪物体calcOpticalFlowPyrLK的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV快速入门:移动物体检测和目标跟踪

    在当今的数字化世界中,计算机视觉技术正在迅速发展并被广泛应用于各种场合。特别是在移动物体检测和目标跟踪领域,这项技术不仅对于安全监控系统至关重要,也在自动驾驶、交互式媒体、机器人技术等多个领域发挥着重要作用。 本文将介绍使用OpenCV进行移动物体检测

    2024年02月04日
    浏览(47)
  • opencv支持的一些计算光流的算法

    Lucas-Kanade(LK)光流算法 Lucas-Kanade(LK)光流算法是一种经典的稀疏光流算法,用于估计图像中局部区域的运动信息。它最初由Bruce D. Lucas和Takeo Kanade于1981年提出,是最早的光流估计方法之一,至今仍然被广泛应用。 LK光流算法的基本原理是利用局部区域的像素灰度值在两帧

    2024年04月27日
    浏览(30)
  • 探索OpenCV的光流算法视频超分与源码实现

    在OpenCV4.0以后,视频图像超分模块已经迁移到opencv_contrib独立仓库。在视频超分有两种形式:结合光流算法实现超分、使用CNN卷积神经网络实现超分。在这里主要探索光流算法实现视频超分,然后进一步分析源码实现。 1、光流算法选择 OpenCV提供多种光流算法:farneback、tvl1、

    2024年02月10日
    浏览(39)
  • Python-OpenCV中的图像处理-物体跟踪

    现在我们知道怎样将一幅图像从 BGR 转换到 HSV 了,我们可以利用这一点来提取带有某个特定颜色的物体。在 HSV 颜色空间中要比在 BGR 空间中更容易表示一个特定颜色。在我们的程序中,我们要提取的是一个蓝色的物体。下面就是就是我们要做的几步: • 从视频中获取每一帧

    2024年02月13日
    浏览(54)
  • 【Opencv】视频跟踪算法KCF

    KCF(Kernelized Correlation Filter)是一种基于核相关滤波器的目标跟踪算法。它通过学习目标的外观特征和使用核相关滤波器进行目标定位。KCF属于传统算法的单目标跟踪器。下面是对KCF跟踪算法的介绍: 目标特征提取:KCF算法使用HOG(Histogram of Oriented Gradients)特征来表示目标的

    2024年02月08日
    浏览(37)
  • 基于光流方法实时跟踪目标在图像中的运动轨迹(python和C++实现)

    光流方法是通过跟踪图像中的特征点(角点,边缘点等),分析这些点在帧与帧之间的运动,来计算物体运动轨迹和速度。具体实现目标如下: 1、选取图像中的易被识别的特征点,如Harris角点,FAST角点。 2、为每个特征点选取一个领域窗口,跟踪该窗口在连续视频帧中的变

    2023年04月24日
    浏览(35)
  • 利用OpenCV计算条形物体的长度

    本文提供了一种利用opencv计算条形物体长度的方法,思路新奇,实现简单,同时也提供了代码实现。 目录 0、前言 1、解决步骤 1.1 利用分割方法得到物体mask 1.2 提取骨骼线 1.3 计算骨架线长度  2、验证         在图像处理中,我们可能会遇到求一个线条长度的场景,比如

    2024年02月15日
    浏览(46)
  • 【计算机视觉】---OpenCV实现物体追踪

    OpenCV中的物体追踪算法基于视觉目标跟踪的原理。物体追踪的目标是在连续的图像序列中定位和跟踪特定物体的位置。 在物体追踪中,我们需要对目标对象进行表示。通常使用边界框(bounding box)来表示目标的位置和大小。边界框是一个矩形区域,由左上角的坐标(x,y)和

    2024年02月08日
    浏览(49)
  • 计算机设计大赛 深度学习的视频多目标跟踪实现

    🔥 优质竞赛项目系列,今天要分享的是 基于深度学习的视频多目标跟踪实现 该项目较为新颖,适合作为竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/postgraduate 基于初始化帧的跟踪,在视频第一帧中选择你的目标,之后交给跟踪算法去

    2024年03月11日
    浏览(120)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包