运动跟踪(一):calcOpticalFlowFarneback(),稠密光流法

关于金字塔LK光流的Demo已经在上一篇的blog中说明了,地址:https://blog.csdn.net/liangchunjiang/article/details/79869830

测试OpenCV的函数calcOpticalFlowFarneback()的效果

void cv::calcOpticalFlowFarneback( InputArray _prev0, InputArray _next0,
                               OutputArray _flow0, double pyr_scale, int levels, int winsize,
                               int iterations, int poly_n, double poly_sigma, int flags )
// 参数说明如下:
// _prev0:输入前一帧图像
// _next0:输入后一帧图像
// _flow0:输出的光流
// pyr_scale:金字塔上下两层之间的尺度关系
// levels:金字塔层数
// winsize:均值窗口大小,越大越能denoise并且能够检测快速移动目标,但会引起模糊运动区域
// iterations:迭代次数
// poly_n:像素领域大小,一般为5,7等
// poly_sigma:高斯标注差,一般为1-1.5
// flags:计算方法。主要包括OPTFLOW_USE_INITIAL_FLOW和OPTFLOW_FARNEBACK_GAUSSIAN

(1)OpenCV Demo

#include "stdafx.h"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <iostream>

using namespace cv;
using namespace std;

static void help()
{
	cout <<
		"\nThis program demonstrates dense optical flow algorithm by Gunnar Farneback\n"
		"Mainly the function: calcOpticalFlowFarneback()\n"
		"Call:\n"
		"./fback\n"
		"This reads from video camera 0\n" << endl;
}
static void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step,
	double, const Scalar& color)
{
	for(int y = 0; y < cflowmap.rows; y += step)
		for(int x = 0; x < cflowmap.cols; x += step)
		{
			const Point2f& fxy = flow.at<Point2f>(y, x);
			line(cflowmap, Point(x,y), Point(cvRound(x+fxy.x), cvRound(y+fxy.y)),
				color);
			circle(cflowmap, Point(x,y), 2, color, -1);
		}
}

int main(int, char**)
{
	VideoCapture cap(0);
	help();
	if( !cap.isOpened() )
		return -1;

	Mat prevgray, gray, flow, cflow, frame;
	namedWindow("flow", 1);

	for(;;)
	{
		cap >> frame;
		cvtColor(frame, gray, COLOR_BGR2GRAY);

		if( prevgray.data )
		{
			calcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
			cvtColor(prevgray, cflow, COLOR_GRAY2BGR);
			drawOptFlowMap(flow, cflow, 16, 1.5, Scalar(0, 255, 0));
			imshow("flow", cflow);
		}
		if(waitKey(30)>=0)
			break;
		std::swap(prevgray, gray);
	}
	return 0;
}
(2)测试效果



参考:

https://blog.csdn.net/yzhang6_10/article/details/51225545



猜你喜欢

转载自blog.csdn.net/liangchunjiang/article/details/79896499