python数字图像处理基础(十一)——光流估计

news2024/9/25 23:25:25

目录

      • 概念
      • Lucas-Kanade算法
      • 函数表达式

概念

光流是空间运动物体在观测成像平面上的像素运动的“瞬时速度”,根据各个像素点的速度矢量特征,可以对图像进行动态分析,例如目标跟踪。要求如下:

  • 亮度恒定:同一点随着时间的变化,其亮度不会发生改变。
  • 小运动:随着时间的变化不会引起位置的剧烈变化,只有小运动情况下才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数。
  • 空间一致:一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知变量。所以需要连立n多个方程求解。

在这里插入图片描述
光流估计是计算图像序列中相邻帧之间的像素运动的过程。它旨在通过分析图像中像素强度的变化,推测场景中物体的运动情况。光流估计可以用于许多计算机视觉应用,如视频稳定、目标跟踪、行为分析等。

在光流估计中,通常假设相邻帧之间的像素强度在空间上是连续变化的。这意味着同一场景中的相邻像素之间存在一定的空间连续性,它们通常随着时间的推移而移动。光流估计的目标是找到一个场景中每个像素点的运动向量,表示它在图像中的位移。

有许多不同的光流估计算法,其中一些常见的包括:

  1. Lucas-Kanade方法: 这是一个基于局部区域的光流估计方法。它假设一个小的图像块内的像素强度变化是线性的,并通过解一个最小二乘问题来计算局部运动。

  2. Horn-Schunck方法: 这是一个全局的光流估计方法,它试图平滑整个场景的光流。该方法在整个图像上定义了一个全局光流场,以最小化场景中所有像素的强度梯度。

  3. Farnebäck方法: 该方法使用多项式来建模局部像素强度变化,并通过计算极小值来估计光流。

  4. DeepFlow: 这是一种深度学习方法,使用卷积神经网络来学习复杂的非线性光流。

光流估计在计算机视觉领域中有着广泛的应用,特别是在视频处理和分析中。通过了解图像序列中物体的运动,我们可以更好地理解场景的动态变化,从而支持许多应用,如行为分析、目标跟踪和视频稳定。

Lucas-Kanade算法

Lucas-Kanade算法是一种经典的光流估计方法,用于计算图像序列中相邻帧之间的像素运动。该算法基于以下假设:在局部区域内,像素强度的运动是线性的。具体来说,该算法考虑图像中的每个像素周围的小邻域,并假设该邻域内的像素强度变化可以用一个位移向量来描述。

算法的基本思想如下:

  1. 选择一个窗口或局部邻域,通常是一个小的正方形区域。
  2. 在该邻域内,假设像素强度在时间上的变化是线性的。
  3. 使用最小二乘法,通过拟合一个位移向量来估计像素的运动。

更具体地,考虑两幅相邻的图像帧 I ( x , y , t 1 ) I(x, y, t_1) I(x,y,t1) I ( x + Δ x , y + Δ y , t 2 ) I(x + \Delta x, y + \Delta y, t_2) I(x+Δx,y+Δy,t2),其中 ( x , y ) (x, y) (x,y)是图像中的坐标, t 1 t_1 t1 t 2 t_2 t2是两个不同的时间点。对于局部邻域内的像素,我们可以将其灰度值变化表示为:

I x = ∂ I ∂ x , I y = ∂ I ∂ y , I t = ∂ I ∂ t I_x = \frac{\partial I}{\partial x}, \quad I_y = \frac{\partial I}{\partial y}, \quad I_t = \frac{\partial I}{\partial t} Ix=xI,Iy=yI,It=tI

其中, I x I_x Ix I y I_y Iy分别是图像在 x x x y y y方向上的空间梯度, I t I_t It是图像在时间上的梯度。

Lucas-Kanade方法通过解决以下线性方程组来估计位移向量 ( Δ x , Δ y ) (\Delta x, \Delta y) (Δx,Δy)

[ I x ( x 1 , y 1 ) I y ( x 1 , y 1 ) I x ( x 2 , y 2 ) I y ( x 2 , y 2 ) ⋮ ⋮ I x ( x n , y n ) I y ( x n , y n ) ] [ Δ x Δ y ] = − [ I t ( x 1 , y 1 ) I t ( x 2 , y 2 ) ⋮ I t ( x n , y n ) ] \begin{bmatrix} I_x(x_1, y_1) & I_y(x_1, y_1) \\ I_x(x_2, y_2) & I_y(x_2, y_2) \\ \vdots & \vdots \\ I_x(x_n, y_n) & I_y(x_n, y_n) \end{bmatrix} \begin{bmatrix} \Delta x \\ \Delta y \end{bmatrix} = -\begin{bmatrix} I_t(x_1, y_1) \\ I_t(x_2, y_2) \\ \vdots \\ I_t(x_n, y_n) \end{bmatrix} Ix(x1,y1)Ix(x2,y2)Ix(xn,yn)Iy(x1,y1)Iy(x2,y2)Iy(xn,yn) [ΔxΔy]= It(x1,y1)It(x2,y2)It(xn,yn)

其中, ( x i , y i ) (x_i, y_i) (xi,yi)表示邻域内的像素坐标, n n n是邻域内像素的数量。通过求解这个线性方程组,可以得到位移向量 ( Δ x , Δ y ) (\Delta x, \Delta y) (Δx,Δy),从而估计像素的运动。

Lucas-Kanade算法的优点在于其计算效率,特别是在局部邻域内像素运动比较均匀的情况下。然而,它对于像素运动比较剧烈或者存在遮挡时可能表现不佳。在实际应用中,Lucas-Kanade算法通常会与金字塔法结合使用,以处理不同尺度上的运动。

  • 简单概括为:

泰勒级数展开

类似索贝尔算子sobel

最小二乘法 线性回归方程

在这里插入图片描述
在这里插入图片描述

函数表达式

  • p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)

作用:用于获得光流估计所需要的角点
参数说明

  • old_gray表示输入图片;
  • mask表示掩模;
  • feature_params:maxCorners=100角点的最大个数(可以小于该数),qualityLevel=0.3角点品质,minDistance=7即在这个范围内只存在一个品质最好的角点;

返回值:为(n, 1, 2)的矩阵

  • pl, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0,None, **lk_params)

作用:获得光流检测后的角点位置

参数说明

  • pl表示光流检测后的角点(特征点)位置,输出跟踪角点(特征点)向量;
  • st表示是否是运动的角点(特征点),找到的状态为1,未找到的状态为0;
  • err表示是否出错;
  • old_gray表示输入前一帧图片;
  • frame_gray表示后一帧图片;
  • p0表示需要检测的角点,为cv2.goodFeaturesToTrack检测到的角点;
  • lk_params:winSize表示选择多少个点进行u和v的求解,即搜索窗口的大小;maxLevel表示空间金字塔的层数

步骤:

角点检测、传入参数

import numpy as np
import cv2

cap = cv2.VideoCapture('./image/test1.mp4')

# 角点检测所需参数
feature_params = dict(maxCorners=100,
                      qualityLevel=0.3,
                      minDistance=7)

# lucas kanade参数
lk_params = dict(winSize=(15, 15),
                 maxLevel=2)  # 窗口大小为15*15,金字塔层数为2

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

# 拿到第一帧图像
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# 返回所有检测特征点,需要输入图像,角点最大数量(效率),品质因子(特征值越大的越好,来筛选)
# 距离相当于这区间有比这个角点强的,就不要这个弱的了
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)  # 寻找角点

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

while True:
    ret, frame = cap.read()  # 这个是取的第二帧图像,上面已经取出了第一帧图像
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 需要传入前一帧和当前图像以及前一帧检测到的角点
    p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)

    # st=1表示
    good_new = p1[st == 1]
    print(p1.shape)  # (n,1,2)
    print(good_new.shape)  # (n, 2)
    good_old = p0[st == 1]

    # 绘制轨迹
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        # new=[692.99805  83.00432]
        a, b = new.ravel()  # 或者[a, b] = new
        c, d = old.ravel()
        # print(a,b,c,d),检测发现a,b,c,d为浮点数,而cv.circle()函数中的圆心坐标不能是浮点数的类型, 要转换成整数才行,于是就使用int()强制类型转换,之后代码成功运行。
        mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)
        # python tolist()方法,将数组或者矩阵转换成列表
        frame = cv2.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)

    img = cv2.add(frame, mask)  # 这个相加不会超出边界

    cv2.imshow('frame', img)
    k = cv2.waitKey(150) & 0xff
    if k == 27:
        break

    # 更新
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1, 1, 2)

cv2.destroyAllWindows()
cap.release()

在这里插入图片描述
(随便用了一个视频试试效果)

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

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

相关文章

FPGA之分布RAM(1)

SLICEM 资源可以实现分布式 RAM。可以实现的 RAM 类型: 单口 RAM 双端口 简单的双端口 四端口 下表给出了通过1SLICEM中的4个LUT可以实现的RAM类型 1.32 X2 Quad Port Distributed RAM 我们介绍过把 6 输入 LUT 当作 2 个 5输入 LUT 使用,在这里&a…

easyui渲染隐藏域<input type=“hidden“ />为textbox可作为分割条使用

最近在修改前端代码的时候&#xff0c;偶然发现使用javascript代码渲染的方式将<input type"hidden" />渲染为textbox时&#xff0c;会显示一个神奇的效果&#xff0c;这个textbox输入框并不会隐藏&#xff0c;而是显示未一个细条&#xff0c;博主发现非常适合…

【2015~2024】大牛直播SDK演化史

大牛直播SDK的由来 大牛直播SDK始于2015年&#xff0c;最初我们只是想做个低延迟的RTMP推拉流解决方案&#xff0c;用于移动单兵等毫秒级延迟的场景下&#xff0c;我们先是实现了Android平台RTMP直播推送模块&#xff0c;当我们用市面上可以找到的RTMP播放器测试时延的时候&am…

Debezium发布历史75

原文地址&#xff1a; https://debezium.io/blog/2019/10/22/audit-logs-with-kogito/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. 使用 Kogito 进行审核日志的管理服务 十月 22, 2019 作者&#xff1a; Mac…

三维重建(3)--单视几何

目录 一、无穷远点、无穷远线、无穷远平面 1、2D平面上的无穷远问题 2、3D平面上的无穷远问题 二、影消点与影消线 1、2D平面上的无穷远点&#xff0c;无穷远线变换 2、影消点 3、影消线 三、单视重构 1、两平行线夹角与影消线关系 2、单视图标定 一、无穷远点、无…

Apifox 国产接口自动化利器 之入门篇

Apifox 产品介绍 Apifox 是集 API 文档、API 调试、API Mock、API 自动化测试多项实用功能为一体的 API 管理平台&#xff0c;定位为 Postman Swagger Mock JMeter。旨在通过一套系统、一份数据&#xff0c;解决多个工具之间的数据同步问题。只需在 Apifox 中定义 API 文档…

Java 全栈知识点问题汇总(上)

Java 全栈知识点问题汇总&#xff08;上&#xff09; 1 Java 基础 1.1 语法基础 面向对象特性&#xff1f;a a b 与 a b 的区别3*0.1 0.3 将会返回什么? true 还是 false?能在 Switch 中使用 String 吗?对equals()和hashCode()的理解?final、finalize 和 finally 的不同…

Win10 打开文件突然鼠标变成一个蓝色大圈卡住点不了也打不开文件,重启电脑也是这样

环境: Win10 专业版 加密客户端环境 问题描述: Win10 打开桌面word文件突然鼠标变成一个蓝色大圈卡住点不了也打不开文件,重启电脑也是这样,只有蓝色圈变大没有鼠标指针出现圈卡着不会动,和那些有鼠标箭头加小蓝色圈不一样 解决方案: 某网上查看的,还是要自己排查…

OceanBase集群扩缩容

​ OceanBase 数据库采用 Shared-Nothing 架构&#xff0c;各个节点之间完全对等&#xff0c;每个节点都有自己的 SQL 引擎、存储引擎、事务引擎&#xff0c;天然支持多租户&#xff0c;租户间资源、数据隔离&#xff0c;集群运行的最小资源单元是Unit&#xff0c;每个租户在每…

LeetCode、2300. 咒语和药水的成功对数【中等,排序+二分】

文章目录 前言LeetCode、2300. 咒语和药水的成功对数【中等&#xff0c;排序二分】题目及类型思路及代码 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域…

聚铭入选“2023中国数字安全能力图谱(精选版)”安全运营领域

近日&#xff0c;国内权威数字安全领域第三方调研机构数世咨询正式发布《2023年度中国数字安全能力图谱&#xff08;精选版&#xff09;》。聚铭网络作为国内领先的安全运营商&#xff0c;凭借在细分领域突出优势&#xff0c;成功入选该图谱“安全运营”领域代表厂商。 据悉&a…

python tkinter 最简洁的计算器按钮排列

代码如下&#xff0c;只要再加上按键绑定事件函数&#xff0c;计算器既可使用了。 import tkinter as tk from tkinter.ttk import Separator,Buttonif __name__ __main__:Buttons [[%,CE,C,←],[1/x,x,√x,],[7, 8, 9, x],[4, 5, 6, -],[1, 2, 3, ],[, 0, ., ]]root tk.T…

MyBatis 使用报错: Can‘t generate mapping method with primitive return type

文章目录 前言问题原因解决方案个人简介 前言 今天在新项目中使用 MyBatis 报如下错误&#xff1a;Cant generate mapping method with primitive return type 问题原因 发现是 Mapper 注解引入错误&#xff0c;错误引入 org.mapstruct.Mapper, 实际应该引入 org.apache.ibat…

FlinkAPI开发之状态管理

案例用到的测试数据请参考文章&#xff1a; Flink自定义Source模拟数据流 原文链接&#xff1a;https://blog.csdn.net/m0_52606060/article/details/135436048 Flink中的状态 概述 有状态的算子 状态的分类 托管状态&#xff08;Managed State&#xff09;和原始状态&…

如何实现 H5 秒开?

我在简历上写了精通 H5&#xff0c;结果面试官上来就问&#xff1a; 同学&#xff0c;你说你精通 H5 &#xff0c;那你能不能说一下怎么实现 H5 秒 由于没怎么做过性能优化&#xff0c;我只能凭着印象&#xff0c;断断续续地罗列了几点&#xff1a; 网络优化&#xff1a;http2、…

JOSEF约瑟 双位置继电器UEG/C-4H4D AC220V 新款导轨安装 端子号可订做

系列型号&#xff1a; UEG/C-2H双稳态中间继电器&#xff1b;UEG/C-1H1D双稳态中间继电器&#xff1b; 双稳态中间继电器UEG/C-4H4D&#xff1b;UEG/C-3H1D双稳态中间继电器&#xff1b; UEG/C-2H2D双稳态中间继电器&#xff1b;UEG/C-4H双稳态中间继电器&#xff1b; UEG/…

HarmonyOS—开发环境诊断的功能

为了大家开发应用/服务的良好体验&#xff0c;DevEco Studio提供了开发环境诊断的功能&#xff0c;帮助大家识别开发环境是否完备。可以在欢迎界面单击Help > Diagnose Development Environment进行诊断。如果已经打开了工程开发界面&#xff0c;也可以在菜单栏单击Help >…

04 SpringBoot整合Druid/MyBatis/事务/AOP+打包项目

整合Druid 项目结构&#xff1a; 引入依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaL…

【网站项目】331基于jsp的超市库存商品管理系统

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【C语言深度剖析——第三节(关键字3)】《C语言深度解剖》+蛋哥分析+个人理解

本文由睡觉待开机原创&#xff0c;未经允许不得转载。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言&#xff0c;共同进步&#xff01; 目录 1.基本数据类型2.sizeof关键字 前言&#xff1a; 本期我们继续探讨关于C深度解剖这本书相关内容&#…