DeepFlow高效的光流匹配算法(下)

2024-08-25 06:08

本文主要是介绍DeepFlow高效的光流匹配算法(下),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本周主要介绍一篇基于传统光流法而改进的实现快速的稠密光流算法。该算法已经集成到OpenCV中,算法介绍网址:http://lear.inrialpes.fr/src/deepmatching/

在介绍该高效的算法之前,我们先介绍一下经典的LK光流算法,所以这篇文章将分为上下两篇。

第一篇DeepFlow高效的光流匹配算法(上)主要介绍光流算法的基础知识,以及理论推导。

第二篇将介绍改进的稠密光流算法匹配算法DeepFlow,并展示Demo效果。

DeepMatching是jerome revaud在2013年开发的一种匹配算法。其目的是计算两幅图像之间的密集对应关系。深度匹配依赖于为匹配图像而设计的深层、多层、卷积结构。它可以处理非刚性变形和重复纹理,因此可以在图像之间存在显著变化的情况下有效地确定稠密对应关系。

在这个匹配算法的基础上又改进了很多其他方面的计算,相关论文主要有:

《DeepMatching: Hierarchical Deformable Dense Matching》

《DeepFlow:Large displacement optical flow with deep matching》

《EpicFlow: Edge-Preserving Interpolation of Correspondences for Optical Flow》

《Fast Optical Flow using Dense Inverse Search》

论文贡献

在经典的光流算法中,在计算小位移的光流算法中在过去几十年中得到了广泛的研究。每个像素的运动被限制在几个像素以内。大位移问题是近几年才引起人们的关注,至今仍是一个悬而未决的问题。大位移光流覆盖了运动不受限制且比物体尺寸更大的更真实情况。为了改善类似问题,正如上一篇文章所述,LK光流又增加了图像金字塔来针对处理大位移的光流的情况。而本文主要的是介绍一种,稠密光流的算法。

DeepFlow可以说是DeepMatching算法的改进算法,将匹配算法与变分方法相结合,应用于光流的计算,是一种适应光流问题的描述子匹配算法,可以提高光流法在快速运动的表现。匹配算法建立在更多层数层,交错卷积和最大池的多层架构之上,这种结构类似于深度卷积网络。同时基于DeepMatching的改进算法还有EpicMatching,以及改进光流计算效率的算法Fast Optical Flow using DIS。

这篇文章做了两个贡献:首先,提出了一种新的匹配算法,称为深度匹配。其次它建立在一个多阶段的架构之上,交错卷积和最大池,就像在深卷积神经网络中那样。深度匹配具有平滑效果,即便在两帧图像之间存在显著变化的情况下,也能够有效的确定稠密对应集。最后,利用brox和malik的方法在大位移光流中进行深度匹配。

这是一种新的匹配算法----深度匹配

       1, 多层结构、交织卷积和最大池

       2, 自平滑匹配

       3, 大位移光流:集成变分方法中深度匹配对大位移显示出很好的鲁棒性

该算法的相比经典光流

经典的光流估计的基本准则是在满足一定前提条件下,最小化能量值。这部分内容可以细细阅读上一篇文章DeepFlow高效的光流匹配算法(上)。

一般情况下,大位移的光流依赖于刚性匹配或者小区域的匹配算法,所用的特征点一般是基于Hog或者sift描述子,采用最近邻方法匹配。

缺点是

1,基于块区域内是光流的一致性,如果在这个块区域内有着不同方向的位移像素,此时这种方法是无法解决的。

2,在纹理不明显的地方这种方法是不可靠的。

该论文里提出的深度匹配算法,介绍如何生成稠密的光流,并且相比较经典算法更能解决以上的一些缺点。

该算法优点有

1,可以应用块区域内的子区域的在一定区域内可以按照不同方向的独立运动

2,使用卷积和最大池快速计算

3,使用了递归的方法

算法的具体步骤

模块一

1,给定两幅图像,我们首先从第一幅图像中提取小的4x4块。

2,使用第一幅图中的patch与第二幅图patch进行卷积

3,此时我们得到了这个patch的响应Map

4,对所有的图像中的patch重复此过程。得到论文中称之为响应图像。

模块二

在模块一得到的响应图上再继续一下操作

1,应用一个max pooling操作符。允许该结果的响应图与patch移动1像素时的响应图相同。

2,由于响应图现在在空间上变化缓慢,这里增加了一个下采样步骤。该步骤可以减少后面步骤的复杂性。

3,然后利用4个响应图的稀疏卷积,即4个位移响应图之和,计算较大patch的响应图。

4,  最后加入一个非线性滤波,以避免过快的收敛到1。结果,得到了虚拟8x8块的响应图,

   其中每个子块的位置在3x3像素附近优化。

5,然后,从这个第二级响应映射的计算,获取虚拟16x16响应映射。

6,重复以上过程

最终迭代过程的结果是一个多尺寸的响应金字塔。在其中扩展了尺度的局部最大值。

对于每个最大值,算法都会回溯到允许获得该最大值的配置,从而产生准密集的对应关系。它是使用动态编程完成的。其中,金字塔是使用自下而上的方法构建的,而提取对应关系则使用自上而下的方法。

上图是论文中如何检索对应关系的示例。

考虑金字塔上的红点是一个局部最大值。

然后它对应于一个叫大的Patch移动。这个最大值是使用4个较小的Patch构建的,检索它们并获得较小的patch匹配。不断的继续下去,就会出现像右边一样出现的小patch。

下面是从重复纹理图像中,利用深度匹配算法提取的对应关系的示例,其中每个颜色都指一个局部最大值。

深度匹配会产生稠密对应点。它使用多尺度的Patch,允许匹配不同比例的对象。成功地处理了纹理重复的图像,而不能处理标准刚性匹配或小patch之间的匹配,也不能处理非刚性变形。最后,允许的变换集提供了一个内置的平滑效果。实际上,局部最大值会导致许多匹配,由于对可行变换集的约束,这些匹配几乎相同。

结论

deepflow使用ldof方法将深度匹配集成到变分方法中。

在经典的数据项和平滑项的基础上,增加了一个匹配项,对输入匹配项和光流估计项之间的差异进行了计算。然后,使用从粗计算到细计算的策略、定点迭代和经典线性系统求解器(如sor)对其进行优化。

DeepFlow拓展算法

以上主要是介绍匹配的方法,能够处理大位移以及块区域中像素不满足光流一致性的前提条件。同时在论文中《Fast Optical Flow using Dense Inverse Search》详细的介绍了如何更加高效的计算光流的值,是一种更为高效的优化方法。

论文中计算光流的步骤:

(1)初始化:对两幅图像构建图像金字塔,以及一些计算量进行初始化

(2)for循环:这一步与LK光流一致,都是从最顶层到最低层的迭代求解的过程

            1 根据当前层的梯度图像计算图像的块状积分图

            2 逆向搜索求解稀疏的图像光流场,(这一步是这篇论文的核心和关键,提出了完全不同于传统光流不一样的求解方法)

            3,根据稀疏光流场计算稠密光流。

(3)最底层的光流resize到跟原始图像一样大小并乘以相应的放大比例,得到最后的光流。

分解这三个部分

1) 图像块状积分图,用于逆向搜索,输入为图像的x,y方向上的梯度Ix,Iy,一般通过soble 算子卷积得到,这一步骤,其实与LK光流求块区域的积分图像没有任何区别。

2)将步骤1)中的输出结果作为这一步的输入,逆向搜索得到稀疏光流场,这一步就是这篇论文的核心所在,是作者创造性的将每一层的光流的迭代量(deltaU,DeltaV)放到了能量最小化公式的左边,从上一篇文章中我们知道传统的光流求解方程为

每一层图像上的光流结果为初始值+迭代量

    u += delU,  v+= delV

最终的求解并优化的残差函数为

在最小化该函数时,需要根据泰勒展开迭代的求解一阶导数S和二阶导数H,就是要多次求解S,H效率低下

而逆向搜索是将上面的公式中写成了

I(x-delU,y-delV,t-1) = I(x+u,y+v,t)

并且最终的残差函数为变成求解

所以与传统光流不同的是,最终求得到光流位移量为

u -= delU,  v-= delV

使用一阶泰勒展开后得到

此时最小化的残差函数变成了

此时从这个残差函数中我们可以得到,每次迭代只需要计算一次S和H,计算速度提升很多,而且精度相差不大。这就是本篇文章的核心。

3)计算稠密光流,输入稀疏光流场,当前层的每一个像素对应的光流等于所有包含该点的图像块对应的稀疏光流的加权求和

以下demo是集成在OpenCV4.0以上版本的DIS光流算法:(说明:将光流场转换到HSV空间中显示,光流的数值用不同颜色来区分,色斑颜色深浅代表运动速率,白色代表物体无运动。)

非Opencv版本的开源代码为:https://github.com/tikroeger/OF_DIS.git   有兴趣的可以试着去研究一番,该源码感觉展示了更多的细节部分,这里给出一个简单的图示:

资源

三维点云论文及相关应用分享

【点云论文速读】基于激光雷达的里程计及3D点云地图中的定位方法

3D目标检测:MV3D-Net

三维点云分割综述(上)

3D-MiniNet: 从点云中学习2D表示以实现快速有效的3D LIDAR语义分割(2020)

win下使用QT添加VTK插件实现点云可视化GUI

JSNet:3D点云的联合实例和语义分割

大场景三维点云的语义分割综述

PCL中outofcore模块---基于核外八叉树的大规模点云的显示

基于局部凹凸性进行目标分割

基于三维卷积神经网络的点云标记

点云的超体素(SuperVoxel)

基于超点图的大规模点云分割

更多文章可查看:点云学习历史文章大汇总

SLAM及AR相关分享

【开源方案共享】ORB-SLAM3开源啦!

【论文速读】AVP-SLAM:自动泊车系统中的语义SLAM

【点云论文速读】StructSLAM:结构化线特征SLAM

SLAM和AR综述

常用的3D深度相机

AR设备单目视觉惯导SLAM算法综述与评价

SLAM综述(4)激光与视觉融合SLAM

Kimera实时重建的语义SLAM系统

SLAM综述(3)-视觉与惯导,视觉与深度学习SLAM

易扩展的SLAM框架-OpenVSLAM

高翔:非结构化道路激光SLAM中的挑战

SLAM综述之Lidar SLAM

基于鱼眼相机的SLAM方法介绍

如果你对本文感兴趣,请后台发送“知识星球”获取二维码,务必按照“姓名+学校/公司+研究方向”备注加入免费知识星球,免费下载pdf文档,和更多热爱分享的小伙伴一起交流吧!

以上内容如有错误请留言评论,欢迎指正交流。如有侵权,请联系删除

扫描二维码

                   关注我们

让我们一起分享一起学习吧!期待有想法,乐于分享的小伙伴加入免费星球注入爱分享的新鲜活力。分享的主题包含但不限于三维视觉,点云,高精地图,自动驾驶,以及机器人等相关的领域。

分享及合作方式:微信“920177957”(需要按要求备注) 联系邮箱:dianyunpcl@163.com,欢迎企业来联系公众号展开合作。

点一下“在看”你会更好看耶

这篇关于DeepFlow高效的光流匹配算法(下)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1104756

相关文章

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

Nginx中location实现多条件匹配的方法详解

《Nginx中location实现多条件匹配的方法详解》在Nginx中,location指令用于匹配请求的URI,虽然location本身是基于单一匹配规则的,但可以通过多种方式实现多个条件的匹配逻辑... 目录1. 概述2. 实现多条件匹配的方式2.1 使用多个 location 块2.2 使用正则表达式

C++实现回文串判断的两种高效方法

《C++实现回文串判断的两种高效方法》文章介绍了两种判断回文串的方法:解法一通过创建新字符串来处理,解法二在原字符串上直接筛选判断,两种方法都使用了双指针法,文中通过代码示例讲解的非常详细,需要的朋友... 目录一、问题描述示例二、解法一:将字母数字连接到新的 string思路代码实现代码解释复杂度分析三、

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为