opencv学习笔记四十二:稠密光流跟踪
程序员文章站
2022-07-11 16:14:50
...
利用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;
}
推荐阅读