光流分析 Optical Flow Lucas-Kanade 算法 DOF Dense Optical Flow

news2024/11/23 14:52:49

光流跟踪算法对车位进行跟踪

概念

光流是空间运动物体在观察成像平面上的像素运动的瞬时速度,是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。
一般而言,光流是由于场景中前景目标本身的移动、相机的运动,或者两者的共同运动所产生的。

  • 当描述部分像素时,称为:稀疏光流
  • 当描述全部像素时,称为:稠密光流

在这里插入图片描述
图中表示一个小球在连续5帧图像中的移动,箭头则表示小球的位移矢量。
简单来说,光流是空间运动物体在观测成像平面上的像素运动的“瞬时速度”,光流的研究是利用图像序列中的像素强度数据的时域变化和相关性来确定各自像素位置的“运动”,研究光流场的目的就是为了从图片序列中近似得到不能直接得到的现实中的运动场。

光流应用于诸多领域:

基于运动的三维重建
视频压缩
视频稳像
目标跟踪与行为识别

基础概念

Lucas-Kanade 算法

光流生效的3个假设

1:亮度恒定:同一个像素点随着时间的变化,也就是说同一个像素点在位置变化前后的亮度值基本保持不变。
2:小范围运动:随着时间的变化,运动的变化,物体的运动不会产生剧烈的变化。这个情况下,灰度对位置的偏导数就可以近似
3:空间一致性:一个场景上,相临近的一块小区域内的点在运动变化后也是相临近的。
在这里插入图片描述
如上图展示的就是一张图像在时刻t到另一个时刻的某个像素的运动变化情况。
在这里插入图片描述
在这里插入图片描述这个不一定可逆啊,什么时候是可逆的呢?可逆的条件是,这个方阵不等于0.
我们回想下之前的角点检测的
1、 在平面处,x的偏导的y的偏导是等于0的。
2、 在直线处,x的偏导的y的偏导有一个是等于0的。
3、 在角点处,x的偏导的y的偏导都变化很大,是有数值的。
这样看来,最有可能在角点处才能有方程的解。因此我们一般都是求角点的前后变化。
那么我们只需要比较前后帧的角点变化来做对比即可得到目标的运动方向

Lucas-Kanade改进算法–图像金字塔

使用图像金字塔来改善LK光流

import cv2
import numpy as np

# cap = cv2.VideoCapture("images/kk 2022-01-23 18-21-21.mp4")
cap = cv2.VideoCapture(0)

# 定义角点检测的参数
feature_params = dict(
    maxCorners=100,  # 最多多少个角点
    qualityLevel=0.3,  # 品质因子,在角点检测中会使用到,品质因子越大,角点质量越高,那么过滤得到的角点就越少
    minDistance=7  # 用于NMS,将最有可能的角点周围某个范围内的角点全部抑制
)

# 定义 lucas kande算法的参数
lk_params = dict(
    winSize=(10, 10),  # 这个就是周围点临近点区域的范围
    maxLevel=2  # 最大的金字塔层数
)

# 拿到第一帧的图像
ret, prev_img = cap.read()
prev_img_gray = cv2.cvtColor(prev_img, cv2.COLOR_BGR2GRAY)

# 先进行角点检测,得到关键点
prev_points = cv2.goodFeaturesToTrack(prev_img_gray, mask=None, **feature_params)

# 制作一个临时的画布,到时候可以将新的一些画的先再mask上画出来,再追加到原始图像上
mask_img = np.zeros_like(prev_img)
while True:

    ret, curr_img = cap.read()
    if curr_img is None:
        print("video is over...")
        break
    curr_img_gray = cv2.cvtColor(curr_img, cv2.COLOR_BGR2GRAY)

    # 光流追踪下
    curr_points, status, err = cv2.calcOpticalFlowPyrLK(prev_img_gray,
                                                       curr_img_gray,
                                                       prev_points,
                                                       None,
                                                       **lk_params)
    # print(status.shape)  # 取值都是1/0, 1表示是可以追踪到的,0表示失去了追踪的。
    good_new = curr_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()

        mask_img = cv2.line(mask_img, pt1=(int(a), int(b)), pt2=(int(c), int(d)), color=(0, 0, 255), thickness=1)
        mask_img = cv2.circle(mask_img, center=(int(a), int(b)), radius=2, color=(255, 0, 0), thickness=2)

    # 将画布上的图像和原始图像叠加,并且展示
    img = cv2.add(curr_img, mask_img)
    cv2.imshow("desct", img)
    if cv2.waitKey(60) & 0xFF == ord('q'):
        print("Bye...")
        break

    # 更新下原始图像,以及重新得到新的点
    prev_img_gray = curr_img_gray.copy()
    prev_points = good_new.reshape(-1, 1, 2)
    if len(prev_points) < 5:
        # 当匹配的太少了,就重新获得当前图像的角点
        prev_points = cv2.goodFeaturesToTrack(curr_img_gray, mask=None, **feature_params)
        mask_img = np.zeros_like(prev_img)  # 重新换个画布

cv2.destroyAllWindows()
cap.release()

DOF Dense Optical Flow in OpenCV

import numpy as np
import cv2


# cap = cv2.VideoCapture('./1.mp4')
cap = cv2.VideoCapture(0)

#获取第一帧
ret, frame1 = cap.read()
prvs = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)
hsv = np.zeros_like(frame1)

#遍历每一行的第1列
hsv[..., 1] = 255

#while True:
while(1):
    ret, frame2 = cap.read()
    next = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)

    # 返回一个两通道的光流向量,实际上是每个点的像素位移值
    flow = cv2.calcOpticalFlowFarneback(prvs, next, None, 0.5, 3, 15, 3, 5, 1.2, 0)

    #print(flow.shape)
    print(flow)

    # 笛卡尔坐标转换为极坐标,获得极轴和极角
    mag, ang = cv2.cartToPolar(flow[..., 0], flow[..., 1])
    hsv[..., 0] = ang*180/np.pi/2
    hsv[..., 2] = cv2.normalize(mag, None, 0, 255, cv2.NORM_MINMAX)
    rgb = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

    cv2.imshow('frame2', rgb)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
    elif k == ord('s'):
        cv2.imwrite('opticalfb.png', frame2)
        cv2.imwrite('opticalhsv.png', rgb)
    prvs = next

cap.release()
cv2.destroyAllWindows()

在这里插入图片描述

CalcOpticalFlowFarneback()

是利用Gunnar Farneback的算法计算全局性的稠密光流算法(即图像上所有像素点的光流都计算出来),由于要计算图像上所有点的光流,故计算耗时,速度慢。它的核心思想主要源于”Two-Frame Motion Estimation Based on PolynomialExpansion”论文
CalcOpticalFlowFarneback()原理

读取视频显示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/378252.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

王道计算机网络课代表 - 考研计算机 第二章 物理层 究极精华总结笔记

本篇博客是考研期间学习王道课程 传送门 的笔记&#xff0c;以及一整年里对 计算机网络 知识点的理解的总结。希望对新一届的计算机考研人提供帮助&#xff01;&#xff01;&#xff01; 关于对 “物理层” 章节知识点总结的十分全面&#xff0c;涵括了《计算机网络》课程里的全…

ARM LDREX/STREX指令以及独占监控器详解

一、目的Linux驱动开发中有一个特别重要的知识点必须掌握&#xff0c;即并发、竞态以及同步。什么是并发&#xff1f;多个执行单元&#xff08;进程、线程、中断&#xff09;同时对一个共享资源的进行访问&#xff1b;此处的共享资源可以是外设、内存或者软件层面的全局变量静态…

Linux服务器磁盘分区、挂载、卸载及报错处理

整体操作是&#xff1a;先对磁盘进行格式化&#xff0c;格式化后挂载到需要的挂载点&#xff0c;最后添加分区启动表&#xff0c;以便下次系统启动时自动挂载。一、linux分区1、Linux来说wulun有几个分区&#xff0c;分给哪一目录使用&#xff0c;他归根结底只有一个根目录&…

计算机操作系统第一章

操作系统引论1.1操作系统的目标和作用定义&#xff1a;操作系统是控制管理计算机系统的硬软件&#xff0c;分配调度资源的系统软件。目标&#xff1a;方便性&#xff0c;有效性&#xff08;提高系统资源的利用率、提高系统的吞吐量&#xff09;&#xff0c;可扩充性&#xff0c…

小红书达人怎么找?保姆级教程来了~

在小红书推广营销中&#xff0c;寻找优质的达人是最头疼的事&#xff0c;许多品牌往往会根据简单的小红书排名来直接进行判断认定&#xff0c;其实在挑选小红书达人时有许多要注意的点&#xff0c;接下来和小编一起根据小红书数据分析工具来筛选合适、优质的达人。 千瓜数据—…

蓝桥杯入门即劝退(二十四)重复的子字符串(被秒杀)

欢迎关注点赞评论&#xff0c;共同学习&#xff0c;共同进步&#xff01; ------持续更新蓝桥杯入门系列算法实例-------- 如果你也喜欢Java和算法&#xff0c;欢迎订阅专栏共同学习交流&#xff01; 你的点赞、关注、评论、是我创作的动力&#xff01; -------希望我的文章…

浅谈MySQL主从复制

目录 1.MySQL主从复制是什么 2.MySQL主从复制的意义 3.MySQL主从复制原理 4.数据同步一致性问题 5.实现方式 1.MySQL主从复制是什么 MySQL主从复制就是指数据可以从一台MySQL的主节点复制到一个或多个从节点。 MySQL默认采用异步复制方式&#xff0c;这样从节点不用一直访…

【博学谷学习记录】超强总结,用心分享丨人工智能 Python基础 个人学习总结之列表排序

目录前言简述list.sort()语法返回值实例无参参数key参数reversesorted()语法返回值实例无参参数key参数reverseoperator.itemgetter功能简述实例List.sort与sored区别sorted原理&#xff1a;Timsort算法扩展list原理数据结构心得前言 经过一周的学习&#xff0c;对Python基础部…

嵌入式入门必看!调试工具安装——基于 AM64x核心板

本章节内容是为评估板串口安装USB转串口驱动程序。驱动适用于CH340、CH341等USB转串口芯片。 USB转串口驱动安装 适用安装环境:Windows 7 64bit、Windows 10 64bit。 本文测试板卡为创龙科技SOM-TL64x核心板,它是一款基于TI Sitara系列AM64x双核ARM Cortex-A53 + 单/四核Cort…

DP(4)--区间DP

将n(1≤n≤200)堆石子绕圆形操场摆放&#xff0c;现要将石子有次序地合并成一堆。 规定每次只能选相邻的两堆石子合并成新的一堆&#xff0c;并将新的一堆的石子数&#xff0c;记为该次合并的得分。 (1)选择一种合并石子的方案&#xff0c;使得做n-1次合并&#xff0c;得分的总…

比特数据结构与算法(第四章_下)二叉树的遍历

本章将会详细讲解二叉树遍历的四种方式&#xff0c;分别为前序遍历、中序遍历、后续遍历和层序遍历。在学习遍历之前&#xff0c;会先带大家回顾一下二叉树的基本概念。学习二叉树的基本操作前&#xff0c;需要先创建一颗二叉树&#xff0c;然后才能学习其相关的基本操作&#…

中国一直是亚马逊云科技在全球业务布局中最重要的国家之一

在走进经济筑底重启回升的2023年&#xff0c;我们该如何直面这场需要时间验证的修复之旅&#xff1f;亚马逊全球副总裁、亚马逊云科技大中华区执行董事张文翊与《经济观察报》App的“企业家说2023”栏目展开对谈&#xff0c;分享亚马逊云科技如何立于云端&#xff0c;帮助企业上…

Android ART dex2oat

一、什么是dex2oat Dex2oat (dalvik excutable file to optimized art file) &#xff0c;是一个对 dex 文件进行编译优化的程序&#xff0c;在我们的 Android 手机中的位置是 /system/bin/dex2oat&#xff0c;对应的源码路径为 android/art/dex2oat/dex2oat.cc&#xff0c;通…

谷歌搜索技巧大全 | 谷歌高级搜索语法指令

谷歌搜索技巧是利用各种高级搜索语法或者搜索指令&#xff0c;让我们能够使用Google进行精确化的搜索&#xff0c;外贸找客户和学术文件查找都可以应用到这些搜索技巧。(大部分命令也适用百度搜索)。Google通过互联网收集数据&#xff0c;抓取有意义的信息&#xff0c;将其存储…

flask入门-4.项目实战

4. 项目实战1 1. 问答平台项目结构搭建 项目结构 config.py hostname "127.0.0.1" port 3306 username "root" password "root"database "flask_qa"# 在 app.config 中设置连接数据库的信息 SQLALCHEMY_DATABASE_URI f"…

【Redis】什么是缓存与数据库双写不一致?怎么解决?

1. 热点缓存重建 我们以热点缓存 key 重建来一步步引出什么是缓存与数据库双写不一致&#xff0c;及其解决办法。 1.1 什么是热点缓存重建 在实际开发中&#xff0c;开发人员使用 “缓存 过期时间” 的策略来实现加速数据读写和内存使用率&#xff0c;这种策略能满足大多数…

ECharts基础知识详细介绍

文章目录知识点ECharts 实例ECharts 基础配置组件seriesdataset用 option 描述图表titletooltiplegend 图例组件toolbox 工具栏坐标轴知识点 ECharts 实例series 与 datasetECharts 基础配置用 option 描述图表坐标系 ECharts 实例 一个网页中可以创建多个 ECharts 实例。每个…

JPA——Java.util.Date和Java.sql.Date

纵观整个项目的字段&#xff0c;最难搞的就是Date类型。今天我们就好好唠唠java中的两个Date类 一、Java.sql.Date 1. 构造方法 Date date new Date(System.currentTimeMillis());System.out.println(date);//2023-02-282. 常用方法&#xff1a; 方法作用void setTime(long…

【Java开发】JUC基础 04:Synchronized、死锁、Lock锁

1 概念介绍并发&#xff1a;同一个对象被多个线程同时操作&#x1f4cc; 线程同步现实生活中&#xff0c;我们会遇到“同一个资源&#xff0c;多个人都想使用”的问题&#xff0c;比如&#xff0c;食堂排队打饭,每个人都想吃饭&#xff0c;最天然的解决办法就是&#xff0c;排队…

强化学习RL 04: Actor-Critic Algorithm

actor: 是policy network&#xff0c;通过生成动作概率分布&#xff0c;用来控制agent运动&#xff0c;类似“运动员”。critic: 是value network&#xff0c;用来给动作进行打分&#xff0c;类似“裁判”。构造这两个网络&#xff0c;并通过environment奖励来学习这两个网络。…