1. 程式人生 > >opencv學習筆記四十二:稠密光流跟蹤

opencv學習筆記四十二:稠密光流跟蹤

利用Gunnar Farneback演算法計算全域性性的稠密光流演算法(即影象上所有畫素點的光流都計算出來),由於要計算影象上所有點的光流,故計算耗時,速度慢  稠密光流需要使用某種插值方法在比較容易跟蹤的畫素之間進行插值以解決那些運動不明確的畫素

calcOpticalFlowFarneback( InputArray prev, InputArray next, InputOutputArray flow,
                                            double pyr_scale, int levels, int winsize,
                                            int iterations, int poly_n, double poly_sigma,
                                            int flags );

prev:前一幀影象  next: 後一幀影象  flow: 輸出的光流矩陣。矩陣大小同輸入的影象一樣大,但是矩陣中的每一個元素可不是一個值,而是兩個值,分別表示這個點在x方向與y方向的運動量(偏移量)。  pyr_scale: 金字塔上下兩層之間的尺度關係  levels: 金字塔層數  winsize: 均值視窗大小,越大越能denoise並且能夠檢測快速移動目標,但會引起模糊運動區域  iterations: 迭代次數  poly_n: 畫素領域大小,一般為5,7等  poly_sigma: 高斯標註差,一般為1-1.5  flags: 計算方法

#include<opencv2\opencv.hpp>
using namespace cv;

Mat frame,preframe, gray, pregray;
Mat flowdata;
int main(int arc, char** argv) {
	VideoCapture capture;
	capture.open("vtest.avi");
	namedWindow("input", CV_WINDOW_AUTOSIZE);
	namedWindow("output", CV_WINDOW_AUTOSIZE);
	capture.read(frame);
	cvtColor(frame, pregray, CV_BGR2GRAY);
	while (capture.read(frame)) {
		imshow("input", frame);
		cvtColor(frame, gray, CV_BGR2GRAY);
		calcOpticalFlowFarneback(pregray, gray, flowdata, 0.5, 3, 15, 3, 5, 1.5, 0);
		cvtColor(pregray, preframe, CV_GRAY2BGR);
		for (int row = 0; row < preframe.rows; row++) {
			for (int col = 0; col < preframe.cols; col++) {
				const Point2f fxy = flowdata.at<Point2f>(row, col);
				if (fxy.x > 2 || fxy.y > 2) {				
					circle(preframe, Point(col, row), 2, Scalar(0, 255, 0), 2);
				}
			}
		}	
		imshow("output", preframe);
		char c = waitKey(100);
		if (c == 27) {
			break;
		}
	}
	capture.release();
	waitKey(0);
	return 0;
}