目标跟踪的点跟踪技术(2)

利用Harris方法找到了特征点后,就可以对特征点进行跟踪了。


所谓“跟踪”,实际上是在下一帧图像中寻找与本图像特征点最相似的点。

何为“相似”?这就需要对每个特征点进行一种描述,这样才能在下一帧图像中寻找(或者说搜索)描述最相似的点。

而搜索的过程显然是比较慢的。早期的计算机速度慢,如果进行“地毯式搜索”,则达不到实时处理速度,因此一些近似方法就这样产生了。


首先是光流法。光流法假定在两帧之间的微小时间间隔内,每个点周围的微小区域是完全一致,不发生任何变化的。

也就是说,假定I为图像的亮度,(x,y)为点的位置,t为当前帧时间,那么

I(x,y,t) = I(x+\Delta x, y + \Delta y, t + \Delta t)


而根据泰勒公式

I(x+\Delta x,y+\Delta y,t+\Delta t) = I(x,y,t) + \frac{\partial I}{\partial x}\Delta x+\frac{\partial I}{\partial y}\Delta y+\frac{\partial I}{\partial t}\Delta t+高阶无穷小

所以

\frac{\partial I}{\partial x}\Delta x+\frac{\partial I}{\partial y}\Delta y+\frac{\partial I}{\partial t}\Delta t = 0

或者

\frac{\partial I}{\partial x}\frac{\Delta x}{\Delta t}+\frac{\partial I}{\partial y}\frac{\Delta y}{\Delta t}+\frac{\partial I}{\partial t}\frac{\Delta t}{\Delta t} = 0


注意到这里出现了物体移动速度的项,可以写成:

\frac{\partial I}{\partial x}V_x+\frac{\partial I}{\partial y}V_y+\frac{\partial I}{\partial t} = 0

其中V_x,V_y为物体(点)移动的速度,也成为”光流“。


更简单可以写成方程:

I_xV_x+I_yV_y=-I_t

因为I_x, I_y  和  I_t 均可直接用减法求出,因此计算光流是非常高效的。

这个方程的未知数超过一个,所以实际计算时是取每个特征点周围5X5的25个点,用最小二乘法计算最优光流。


OpenCV中提供了光流法的函数,使用方便。

其中比较重要的函数是goodFeaturesToTrackcalcOpticalFlowPyrLK,前一个用来获取特征点,后一个进行光流跟踪。


#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
	VideoCapture cap(0);
	cap.set( CV_CAP_PROP_FRAME_WIDTH,320);
	cap.set( CV_CAP_PROP_FRAME_HEIGHT,240 );
	if (!cap.isOpened()) {
		cout << "open camera error." << endl;
		exit(-1);
	}
	namedWindow("disp");

	Mat img, gray, prevGray;
	vector<Point2f> pts, prevPts;
	vector<unsigned char> status;
	vector<float> err;
	int maxCorners = 20;
	int iFrame = 0;
	while (true) {
		cap >> img;
		cvtColor(img, gray, CV_RGB2GRAY);
		
		if (iFrame == 0) {
			goodFeaturesToTrack(gray, pts, maxCorners, 0.1, 5);
			if (pts.size() == 0){
				iFrame = 0;
				continue;
			} else {
				TermCriteria termcrit(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03);
				Size subPixWinSize(10,10);
				cornerSubPix(gray, pts, subPixWinSize, Size(-1,-1), termcrit);
			}

		} else {
			calcOpticalFlowPyrLK(prevGray, gray, prevPts, pts, status, err);
		}

		for (int i = 0; i < pts.size(); i++) {
			circle(img, pts[i], 2, Scalar(255, 255, 0), 1);
		}
		imshow("disp", img);

		swap(prevGray, gray);
		swap(prevPts, pts);
		iFrame++;
		if (waitKey(30) >= 0)
			break;
	}
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值