首页 > 其他分享 >视频处理之光流估计

视频处理之光流估计

时间:2024-06-03 22:59:23浏览次数:21  
标签:视频 gray frame cv2 角点 估计 之光流 prev points

引言:

        光流估计是计算图像序列中物体运动的方法之一。在计算机视觉和图像处理中,光流被用来估计图像中像素的运动方向和速度。它是通过比较两帧图像中相邻像素的亮度值来实现的。

那么会实现什么样子的功能呢?我们来看一下效果

        上图就是某视频中截取到的一帧画面,那么我们接下来看一下光流估计可以达到什么样子的效果

        我们可以看见上图中有很多的光点,以及出现了很多绿色的轨迹,这些绿色的轨迹就是视频中人物运动的轨迹。通过这些轨迹我们可以更好的识别图像中的运动物体,并对它们进行分割。通过检测物体的运动模式,可以更准确地对物体进行识别和跟踪。

那么我们接下来看一下如何通过代码实现

import cv2
import numpy as np

# 打开视频文件
cap = cv2.VideoCapture(r'C:\Users\35173\Desktop\test.avi')

# 获取第一帧
ret, first_frame = cap.read()
if not ret:
    print("Error: Could not read the first frame.")
    cap.release()
    exit()

# 将第一帧转换为灰度图像
prev_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)

第一部分:

导入必要的库,开始读取文件,视频文件用VideoCapture来进行读取,同时逐帧的读取视频的读取视频,如果读取不到就释放,这个时候要考虑是不是文件地址没选成功,或者视频损坏

# 将第一帧转换为灰度图像
prev_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)
# 角点检测参数
feature_params = dict(maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)
# Lucas-Kanade光流法参数
lk_params = dict(winSize=(15, 15), maxLevel=2,
                 criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# 使用Shi-Tomasi角点检测器检测第一帧中的角点
prev_points = cv2.goodFeaturesToTrack(prev_gray, mask=None, **feature_params)
# 创建用于绘制轨迹的掩膜
mask = np.zeros_like(first_frame)

第二部分:

首先将第一帧转化为灰度图这一步很重要用于减少计算量,然后设置以下角点检测的参数。其中,各参数含义如下所示:

  • maxCorners: 最大角点数,表示算法尝试找到的角点的最大数量。
  • qualityLevel: 质量水平,一个介于0和1之间的值,用于评估角点的可靠性。较高的值意味着更严格的质量评估。
  • minDistance: 角点之间的最小欧氏距离,用于确保角点的分布。
  • blockSize: 用于提取角点的图像块的大小,影响角点检测的精度。

然后再设置一些光流检测的参数,各参数的含义如下:

  • winSize: 光流计算中使用的窗口大小。较大的窗口可以提供更平滑的光流场,但可能会降低精度。
  • maxLevel: 金字塔的最大层数,用于多尺度光流估计。较高的值可以提供更好的性能,但会增加计算量。
  • criteria: 终止条件,由三部分组成:
    • cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT: 表示当满足以下任一条件时停止迭代:达到指定的精度(EPS)或迭代次数(COUNT)。
    • 10: 迭代次数的阈值。
    • 0.03: 精度的阈值,即算法认为已经找到足够好的匹配时的误差阈值。

然后使用角点检测器来检测第一帧的角点,同时返回的prev_points是一个数组,包含了检测到的角点的坐标。然后创建了一个大小和第一帧相似的全零矩阵作为掩膜。

while True:
    ret, frame = cap.read()
    if not ret:
        print("Error: Could not read frame.")
        break

    # 将当前帧转换为灰度图像
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 计算光流
    next_points, status, err = cv2.calcOpticalFlowPyrLK(prev_gray, gray, prev_points, None, **lk_params)

    # 选择好的跟踪点
    good_new = next_points[status == 1]
    good_old = prev_points[status == 1]

    # 绘制跟踪结果
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        a, b = new.ravel()
        c, d = old.ravel()
        a, b, c, d = int(a), int(b), int(c), int(d)  # 将坐标转换为整数
        mask = cv2.line(mask, (a, b), (c, d), (0, 255, 0), 2)
        frame = cv2.circle(frame, (a, b), 5, (0, 0, 255), -1)

    img = cv2.add(frame, mask)

    # 显示结果
    cv2.imshow('Optical Flow', img)

第三部分:

在逐帧的读取视频并转化为灰度图之后开始计算光流,

使用cv2.calcOpticalFlowPyrLK函数计算前一帧(prev_gray)和当前帧(gray)之间的光流。prev_points是前一帧中检测到的角点。该函数返回三个值:

  • next_points: 当前帧中角点的预测位置。
  • status: 一个布尔数组,表示每个角点是否成功跟踪。
  • err: 一个数组,包含每个角点跟踪的误差。

        根据status数组,选择成功跟踪的角点。statusTrue(即数值为1)表示角点被成功跟踪。紧接着遍历成功跟踪的角点,new是当前帧中角点的位置,old是前一帧中角点的位置。接着将角点坐标降维成一维之后从浮点数转换为整数,因为图像坐标必须是整数。然后使用cv2.line函数在掩膜mask上绘制从旧位置到新位置的绿色线条,以可视化角点的移动轨迹。同时在当前帧的角点上绘制新的圆圈,表示角点的新位置。将当前帧和掩膜合并之后显示它们的结果。

    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

    # 更新前一帧和前一帧的角点
    prev_gray = gray.copy()
    prev_points = good_new.reshape(-1, 1, 2)

# 释放视频捕获对象并关闭所有窗口
cap.release()
cv2.destroyAllWindows()

第四部分:

作为结尾部分,其中cv2.waitKey函数会等待用户按下一个键盘按键,参数30表示等待时间(毫秒)。如果30毫秒内没有按键被按下,函数返回-1,如果用户按下了Esc键(ASCII码为27),则k的值将等于27。如果检测到这个值,循环将通过break语句被终止,这意味着视频处理和光流估计将停止。同时更新光流估计中使用的前一帧和前一帧的角点。最后释放掉获取到的资源,并且关闭掉所有窗口,避免对系统造成不必要的负担。

完整代码:

import cv2
import numpy as np

# 打开视频文件
cap = cv2.VideoCapture(r'C:\Users\35173\Desktop\test.avi')

# 获取第一帧
ret, first_frame = cap.read()
if not ret:
    print("Error: Could not read the first frame.")
    cap.release()
    exit()

# 将第一帧转换为灰度图像
prev_gray = cv2.cvtColor(first_frame, cv2.COLOR_BGR2GRAY)
# 角点检测参数
feature_params = dict(maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)
# Lucas-Kanade光流法参数
lk_params = dict(winSize=(15, 15), maxLevel=2,
                 criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# 使用Shi-Tomasi角点检测器检测第一帧中的角点
prev_points = cv2.goodFeaturesToTrack(prev_gray, mask=None, **feature_params)
# 创建用于绘制轨迹的掩膜
mask = np.zeros_like(first_frame)

while True:
    ret, frame = cap.read()
    if not ret:
        print("Error: Could not read frame.")
        break

    # 将当前帧转换为灰度图像
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 计算光流
    next_points, status, err = cv2.calcOpticalFlowPyrLK(prev_gray, gray, prev_points, None, **lk_params)

    # 选择好的跟踪点
    good_new = next_points[status == 1]
    good_old = prev_points[status == 1]

    # 绘制跟踪结果
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        a, b = new.ravel()
        c, d = old.ravel()
        a, b, c, d = int(a), int(b), int(c), int(d)  # 将坐标转换为整数
        mask = cv2.line(mask, (a, b), (c, d), (0, 255, 0), 2)
        frame = cv2.circle(frame, (a, b), 5, (0, 0, 255), -1)

    img = cv2.add(frame, mask)

    # 显示结果
    cv2.imshow('Optical Flow', img)



    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break

    # 更新前一帧和前一帧的角点
    prev_gray = gray.copy()
    prev_points = good_new.reshape(-1, 1, 2)

# 释放视频捕获对象并关闭所有窗口
cap.release()
cv2.destroyAllWindows()

标签:视频,gray,frame,cv2,角点,估计,之光流,prev,points
From: https://blog.csdn.net/2301_77444219/article/details/139423023

相关文章

  • 通过GB/T28181国标协议实现视频监控平台间的级联对接
    随着近几年网络视频监控应用范围的扩大,越来越多的政府部门及跨区域行业单位对视频监控的需求已经不仅仅满足于本地的联网监控,更多正在探索在原有本地联网监控基础上,建设省级乃至全国范围内跨区域的监控联网,全面打造数据共享平台。Liveweb视频融合云平台具备视频监控直播、云端......
  • 电池电动汽车的健康状态 SOH 和充电状态 SOC 估计研究(Matlab代码实现)
     ......
  • (最新方法)最简单小鹅通视频下载分析及小白工具下载实现
    本文所有教程及源码、软件仅为技术研究。不涉及计算机信息系统功能的删除、修改、增加、干扰,更不会影响计算机信息系统的正常运行,不得将代码用于非法用途,如侵立删!此方法包含步骤图示:小鹅通视频下载分析及工具实现操作环境win10,win11方案工具识别工具+链接置换工具+下载器......
  • BK7258--wifi音视频soc芯片,1080P H264 wifi低功耗保活,内置BLE,音频code,psram,flash,USB2.
    BK7258是上海博通推出的高度集成的Wi-Fi+BLE combo音视频芯片,支持UVC和DVP摄像头,该芯片集成音视频外设及接口,1080P,H.264,低功耗,内置flash,dsp,psram,驱屏,回声消除及降噪等,广泛适用于可视猫眼,门锁,门铃,ipc,内窥,儿童相机等应用市场。可视门铃应用:DVP接口支持720p25fps图像采集;MJPE......
  • 短视频矩阵系统升级,开发完善功能强大的AI短视频矩阵助手
    一、短视频矩阵的趋势平台整合:未来,短视频平台之间的整合将更加紧密。短视频矩阵将更加注重跨平台的整合营销,使创作者能在一个统一的界面中管理多个短视频平台,从而提高运营效率,并实现更加全面的营销覆盖。数据驱动:数据将成为短视频矩阵的核心驱动力。借助丰富的数据分析工具,短......
  • YOLOv8输出视频.avi有损转.mp4(使用ffmpeg)
    问题:在使用YOLOv8模型直接推理视频后,存储的视频文件格式默认为.avi格式,且推理出的视频占用空间巨大,亲测500多M的视频推理完保存的结果视频有25个多G,此时当视频在服务器上时,想预览就需要下载至本地,对于这么大的视频要耗费大量时间。解决办法:可以使用ffmpeg视频处理工具对.avi格......
  • Mac电脑在线视频播放器:IINA for Mac v1.3.4中文版下载
    IINA是一款优秀的Mac平台视频播放软件,能够支持几乎所有常见的视频格式和编解码器,包括4K、HEVC、H.264等。软件采用了现代化的设计风格,界面简洁清晰,操作简便。同时还支持视频播放过程中的画中画、自定义快捷键、在线字幕搜索等功能,用户体验非常优秀。除此之外,IINA还支持AirP......
  • 抖音 QQ 视频搞笑聊天记录,让你轻松日进斗金!
    你想知道如何用趣味搞笑的聊天记录吸引年轻群体,并实现视频的商业价值变现吗?这个经过实操验证的成熟项目,将为你揭开谜底!我们的玩法简单又有趣,就是通过制作搞笑聊天记录视频,吸引年轻人的关注。这些聊天记录可以是真实的生活对话,也可以是虚构的创意内容,只要能让观众捧腹大笑,......
  • 车载诊断内容汇总(培训+视频)
    车载诊断内容汇总我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师:屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神......
  • 借助AI大模型,三分钟原创一部儿童故事短视频(附完整操作步骤)
    前面文章的介绍,我们可以通过在自己笔记本电脑上部署的Llama3大模型生成文章、文本润色、生成摘要等。今天我们更进一步,在文本的基础上,快速制作一部儿童故事短视频,且可根据自己需要完全原创……前提:有AI大模型对话机器人第一种方式(推荐),可参考前面文章,自己部署大模型,深入体......