稠密光流跟踪是将当前帧的所有像素点与前一帧比较,有变化的标记出来。对比的点比较多,不是对比变化的那几个特征点。所以速度较慢。没有稀疏光流的速度快。但有的时候效果比稀疏光流要好。
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
#include
#include
using namespace cv;
using namespace std;
void drawOpticalFlowHF(const Mat& flowData, Mat& image)
{
for (int row = 0; row < flowData.rows; row++)
{
for (int col = 0; col < flowData.cols; col++)
{
const Point2f fxy = flowData.at(row, col);
if (fxy.x > 2 || fxy.y > 2)
{
line(image, Point(col, row), Point(col + fxy.y, row + fxy.x), Scalar(0,255,0), 2, 16);
circle(image, Point(col, row), 2, Scalar(0, 0, 255), -1);
}
}
}
}
int main()
{
VideoCapture capture(0);
if (!capture.isOpened())
{
puts("dont open video.");
system("pause");
return -1;
}
Mat frame, gray, prev_frame, prev_gray, flowResult, flowData;
// 第一帧
capture.read(frame);
cvtColor(frame, prev_gray, COLOR_BGR2GRAY);
// 从第二帧开始
while (capture.read(frame))
{
cvtColor(frame, gray, COLOR_BGR2GRAY);
if (!prev_gray.empty())
{
calcOpticalFlowFarneback(prev_gray, gray, flowData, 0.5, 3, 15, 3, 5, 1.2, 0);
cvtColor(prev_gray, flowResult, COLOR_GRAY2BGR);
drawOpticalFlowHF(flowData, flowResult);
imshow("flow video", flowResult);
imshow("input video", frame);
}
if (27 == waitKey(60)) break;
}
capture.release();
waitKey(0);
return 0;
}