Fast特征点与LK光流法

博客:http://blog.csdn.net/qianxin_dh


一.光流法回顾

       光流作为飞行昆虫对外界光学信息感知,处理的方式,其概念在1950年有Gibson首次提出,80年代初期Horn和Schunck以及Lucas和Kanade做了奠基性工作,之后光流法被广泛研究,很多种方法被相继提出。1994年,Barron等对当时的有代表性光流法进行了详细的分类和评价,对光流法的发展起到了关键性作用。Barron按照理论基础和数学方法的区别把光流法分成五类:基于偏微分(梯度)的方法,基于特征匹配法的方法,基于能量的方法,基于相位的方法,其中最常用的方法为基于偏微分的方法和基于特征匹配的方法。2011年,S.Baker等研究发现大多数的光流法都是对数据项和平滑项的和的优化,并参考Barron-Fleet的分类法,根据数据项和平滑项及系数的不同取法分亮度约束法,变分法,一阶法,二阶法,空间约束法等等,并建立了Middlebury Flow数据库,包含图像序列,真实光流和对光流算法的评价。

      根据光流计算的约束条件,可分为全局光流法局部光流法,前者的代表是Horn & Schunck(HS)法及其衍生方法,后者的代表是Lucas & Kanade(LK)法及其衍生方法。使用全局光流法直接利用了整幅图像的稠密光流,免去了提取“good feature”的过程,但是由于计算量过大,影响了算法的实时性。此外,全局光流法的全局约束也会使误差在整幅图像上传播,影响光流估计准确性。相比之下,局部光流法可以在计算光流之前提取特征点,利用这些特征点的稀疏光流代表整幅图像的稠密光流,可以同时提高光流的准确性并减少计算时间。Chaos对使用光流进行视觉导航的8种系统进行了统计,LK法由于其计算的简便性及时间消耗少而最为常用。生物学家也指出果蝇也是靠特征点和光流进行导航。因此,特征点的选取对于稀疏光流的运动估计非常关键。

       基于特征点的光流法只在第一帧提取特征点,然后计算特征点的光流,所以用于光流计算的特征点应该不仅可以代表图像信息,而且能够提高光流的准确性。传统的特征点是针对一副图像提取角点或纹理,如图像梯度的极值处以及Laplacian的零点,但它们可能是深度不连续点或是光滑表面上的亮度异常点,会导致光流计算不准确。SIFT或SURF特征点利用了高斯差分金字塔的局部极值点具有尺度不变性的特点,提取的特征点对图像信息具有很强的代表性。基于光流运动方程的Shi & Tomasi法提取的good feature,以包含两幅图像信息的局部邻域的矩阵的特征值为量度,易于利用光流进行跟踪,具有局部性和仿射不变形。

       

二.Fast特征点

         文章应该是《Machine Learning for high-speed corner detection》,FAST特征顾名思义,就是快,它快于现有其它角点的检测速度,在一些对实时性要求较高的条件下,可以考虑使用该特征。FAST特征是基于特征点周围的图像灰度值,检测候选特征点周围一圈的像素值,若该像素点圆形邻域圆周上有3/4的点和该像素点灰度值差足够大,则认为该像素点为一个特征点。如下入所示:

Fast特征点与LK光流法_第1张图片

三.代码

       Fast特征和LK光流法相结合,实现对摄像头里运动物体的特征点跟踪。(配置:vs2008 + opencv2.3.1)


头文件:

#include 
#include 
#include 
#include 
#include 

class FeatureTracker
{
private:
    cv::Mat gray;  //当前灰度图像
    cv::Mat gray_prev; //之前灰度图像
    //两幅图像间跟踪的特征点 0->1
    std::vectorpoints[2];
    //跟踪的点初始位置
    std::vectorinitial;
    std::vectorfeatures;       //检测到的特征
    std::vector status;      //检测到的特征的状态
    std::vector err;           //跟踪过程中的错误
public:
	FeatureTracker();
	~FeatureTracker();

	void process(cv::Mat& frame ,cv::Mat& output);
	void detectFeaturePoints(cv::Mat& frame);
	bool addNewPoints();
	bool acceptTrackedPoint(int i);
	void handleTrackedPoints(cv::Mat& frame,cv::Mat& output);
};


函数实现:

#include "FeatureTracker.h"

FeatureTracker:: FeatureTracker()
{
}

FeatureTracker:: ~FeatureTracker()
{

}

void FeatureTracker::detectFeaturePoints(cv::Mat& frame)
{
	std::vector keyPoints;

	cv::FastFeatureDetector fast(10);  //检测阈值
	fast.detect(frame,keyPoints);
	features.clear();

	for (int i=0;i2);
}

void FeatureTracker::handleTrackedPoints(cv::Mat& frame,cv::Mat& output)
{
	for(int i=0;i图2中的输入点坐标
		status,                    //跟踪成功
		err);                     //跟踪错误

	//遍历所有跟踪的点进行筛选
	int k=0;
	for(int i=0;i

主函数:

// OpticlaTracking.cpp 
//created by qianxin_dh 

#include "stdafx.h"
#include "FeatureTracker.h"

using namespace cv ;
using namespace std;


const char* winname="LK	 Tracking";

int main()
{
	VideoCapture capture;
	capture.open(1);

	namedWindow(winname,CV_WINDOW_AUTOSIZE);

	Mat frame;
	Mat output;
	FeatureTracker lk;

	while (capture>>frame)
	{
		lk.process(frame,output);
		imshow(winname, output);
		char c=waitKey(33);
		if (c==27) {
			break;
		}
	}
	return 0;
}


你可能感兴趣的:(opencv,目标跟踪,图像处理)