opencv求两张图像光流_光流估计——从传统方法到深度学习

3f1d4edc275a52c4fa663a48f172cb58.png

1.摘要

近年来,深度学习技术,作为一把利剑,广泛地应用于计算机视觉等人工智能领域。如今时常见诸报端的“人工智能时代”,从技术角度看,是“深度学习时代”。光流估计是计算机视觉研究中的一个重要方向,然而,因为其不容易在应用中“显式”地呈现,而未被大众熟知。随着计算机视觉学界从图像理解转向视频理解,互联网用户从发布图片朋友圈转向发布短视频,人们对视频的研究和应用的关注不断增强。光流估计作为视频理解的隐形战士,等着我们去寻找其踪迹。 本文首先介绍了什么是视频光流估计;再介绍光流估计的算法原理,包括最为经典的Lucas-Kanade算法和深度学习时代光流估计算法代表FlowNet/FlowNet2;最后,介绍了视频光流估计的若干应用。希望对光流估计的算法和应用有个较为全面的介绍。

2.介绍

光流,顾名思义,光的流动。比如人眼感受到的夜空中划过的流星。在计算机视觉中,定义图像中对象的移动,这个移动可以是相机移动或者物体移动引起的。具体是指,视频图像的一帧中的代表同一对象(物体)像素点移动到下一帧的移动量,使用二维向量表示。如图2-1。

9990455ba9fc42dcbfdef31920137883.gif
图2-1 光流示意图

根据是否选取图像稀疏点进行光流估计,可以将光流估计分为稀疏光流和稠密光流,如图2,左图选取了一些特征明显(梯度较大)的点进行光流估计和跟踪,右图为连续帧稠密光流示意图。

6f043ec9caa7ffd0d40d482711cbd890.gif
图2-2 左图 稀疏点光流,右图 稠密光流

稠密光流描述图像每个像素向下一帧运动的光流,为了方便表示,使用不同的颜色和亮度表示光流的大小和方向,如图2-2右图的不同颜色。图2-3展示了一种光流和颜色的映射关系,使用颜色表示光流的方向,亮度表示光流的大小。

16acdc3d4a52ea403f83ebadadd64741.png
图2-3 稠密光流表示颜色空间

3.算法

最为常用的视觉算法库OpenCV中,提供光流估计算法接口,包括稀疏光流估计算法cv2.calcOpticalFlowPyrLK(),和稠密光流估计cv2.calcOpticalFlowFarneback()。其中稀疏光流估计算法为Lucas-Kanade算法,该算法为1981年由Lucas和Kanade两位科学家提出的,最为经典也较容易理解的算法,下文将以此为例介绍传统光流算法。 对于最新的深度学习光流估计算法,FlowNet的作者于2015年首先使用CNN解决光流估计问题,取得了较好的结果,并且在CVPR2017上发表改进版本FlowNet2.0,成为当时State-of-the-art的方法。截止到现在,FlowNet和FlowNet2.0依然和深度学习光流估计算法中引用率最高的论文,分别引用790次和552次。因此,深度学习光流估计算法将以FlowNet/FlowNet2.0为例介绍。

3.1 传统算法 Lucas-Kanade

为了将光流估计进行建模,Lucas-Kanade做了两个重要的假设,分别是亮度不变假设和邻域光流相似假设。

3.1.1 亮度不变假设

81f609eb6bea0b62c072c801d538f209.png
图3-1-1 - Lucas-Kanade 亮度不变假设

亮度不变假设如图3-1-1,假设待估计光流的两帧图像的同一物体的亮度不变࿰

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV 中,可以使用 PnP(Perspective-n-Point)算法来估计两张图像之间的位姿。PnP 算法是一种基于相机内参和三维点云的姿态估计方法,可以根据图片中的特征点和三维点云计算出相机在空间中的位置和方向。 以下是 OpenCV 中实现 PnP 算法的大致步骤: 1. 从两张图像中提取 SIFT 或 SURF 特征点,并进行匹配,得到一组匹配点对。 2. 根据匹配点对,估计出三维空间中的点云。 3. 定义相机内参矩阵,通过 PnP 算法计算相机外参矩阵(即相机在世界坐标系中的位置和方向)。 4. 通过相机内参矩阵和外参矩阵,将三维点云投影到二维平面上,与原始图片进行比较,计算误差并调整相机内参和外参矩阵。 5. 重复以上步骤,直到误差满足要。 以下是一个简单的 Python 代码示例,展示了如何使用 OpenCV 中的 PnP 算法进行位姿估计: ```python import cv2 import numpy as np # 读取两张图片 img1 = cv2.imread('img1.jpg') img2 = cv2.imread('img2.jpg') # 提取 SIFT 特征点并进行匹配 sift = cv2.xfeatures2d.SIFT_create() kp1, des1 = sift.detectAndCompute(img1, None) kp2, des2 = sift.detectAndCompute(img2, None) bf = cv2.BFMatcher() matches = bf.match(des1, des2) # 选取最优匹配点对 matches = sorted(matches, key=lambda x: x.distance) good_matches = matches[:50] pts1 = np.float32([kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2) pts2 = np.float32([kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2) # 估计相机位姿 K = np.array([[800, 0, 320], [0, 800, 240], [0, 0, 1]]) dist_coefs = np.zeros(5) success, rvec, tvec = cv2.solvePnP(pts1, pts2, K, dist_coefs) # 打印相机位姿 print("Rotation vector:\n", rvec) print("Translation vector:\n", tvec) ``` 需要注意的是,以上代码仅仅只是一个简单的示例,实际应用中还需要进行一些额外的处理,例如去除误匹配点等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值