视觉SLAM实践入门——(19)视觉里程计之多层光流法(光流金字塔)

本文介绍了光流法在处理大运动场景时的问题,即单层光流法由于窗口限制可能导致跟踪丢失。多层光流法通过图像金字塔解决了这一问题,通过对上层图像的光流估计来改善下层的跟踪效果。文中详细阐述了多层光流法的步骤,并给出了OpenCV中的光流金字塔接口。此外,还提供了一个自定义的光流跟踪类实现,包括反向光流法和单层光流法的计算过程。最后,通过实例展示了不同光流方法的跟踪结果,并与OpenCV的光流估计进行了比较。

对于单层光流法,每次迭代求解增量方程使用了8x8窗口的所有像素点的信息,当运动较大,使得估计点在下一帧图像的位置超出了这个窗口,这时光流法就会跟丢这个点

多层光流法基于图像金字塔,通过对上层图像使用光流法得到估计值(同样的8x8窗口,但是上层图像分辨率较小,因此可以估计更大的运动),再将估计值反馈到下层作为计算的初始值,从而解决单层光流法无法估计较大运动等问题

 

多层光流法的过程

1、寻找GFTT角点

2、计算图像金字塔

3、对图像金字塔,从上至下使用单层光流法

 

 

验证时可以与opencv的光流金字塔估计的位置进行对比,opencv提供的光流金字塔接口:

void cv::calcOpticalFlowPyrLK	(	
InputArray 	prevImg,
InputArray 	nextImg,
InputArray 	prevPts,
InputOutputArray 	nextPts,
OutputArray 	status,
OutputArray 	err,
Size 	winSize = Size(21, 21),
int 	maxLevel = 3,
TermCriteria 	criteria = TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
int 	flags = 0,
double 	minEigThreshold = 1e-4 
)

 

 

#include <iostream>
#include <string>
using namespace std;

//#include <list>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
using namespace cv;

#include <Eigen/Core>
#include <Eigen/Dense>


//定义一个用于光流跟踪的类
class OpticalFlowTracker
{
public:
	OpticalFlowTracker(
		const Mat &img1,
		const Mat &img2,
		const vector<KeyPoint> &kp1,
		vector<KeyPoint> &kp2,
		vector<bool> &success,
		bool inverse = true,
		bool has_initial = false
	) : _img1(img1), _img2(img2), _kp1(kp1), _kp2(kp2), _success(success), _inverse(inverse), _has_initial(has_initial){};

	void calculateOpticalFlow(const Range &range);
		 
private:
	const Mat &_img1;
	const Mat &_img2;
	const vector<KeyPoint> &_kp1;
	vector<KeyPoint> &_kp2;
	vector<bool> &_success;
	bool _inverse = true;		//_inverse = true 使用反向光流法
	bool _has_initial = false;	//单目相机初始化后,这个标志置为true
};


//下面使用了源码,没有修改
inline float GetPixelValue(const cv::Mat &img, float x, float y) {
    //不严谨的边界检测
	//1:后面使用了多个像素进行平滑处理,如果传入点在最后一行会导致指针越界
	//2:如果传入点在最后一列,不再是使用2*2方块进行平滑处理(其中一个点位于下一行的第一列)
    if (x < 0) x = 0;
    if (y < 0) y = 0;
    if (x >= img.cols) x = img.cols
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值