稠密光临

// 稠密光流.cpp: 定义控制台应用程序的入口点。
//稠密光流不对特征点跟踪,而是每次扫描整幅图像,显示运动的像素点,所以稠密光流运算速度慢
//
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
static void drawOpticalFlowHF(const Mat &flowdata, Mat& image, int step);

void main(int argc, char** argv)
{
	VideoCapture capture;
	capture.open(0);
	if (!capture.isOpened()) cout << "video not open.." << endl;

	Mat frame, gray;
	Mat prev_frame, prev_gray;
	Mat flowResult, flowdata;//稠密光流的结果和行,x,y位移数据
	capture.read(frame); // 先取出第一帧图像
	cvtColor(frame, prev_gray, COLOR_BGR2GRAY);

	// 从第二帧数据开始的每一帧都与第一帧进行比较
	while (capture.read(frame))
	{
		cvtColor(frame, gray, COLOR_BGR2GRAY);
		if (!prev_gray.empty())
		{
			/*
			void calcOpticalFlowFarneback( // 稠密光流跟踪
			InputArray prev, // 输入前一帧图像
			InputArray next, // 输入后一帧图像
			InputOutputArray flow, // 输出的光流
			double pyr_scale, // 金字塔上下两层之间的尺度关系
			int levels, // 金字塔层数
			int winsize, // 均值窗口大小,越大越能denoise并且能够检测快速移动目标,但会引起模糊运动区域
			int iterations, // 迭代次数
			int poly_n, // 像素领域大小,一般为5,7等
			double poly_sigma, // 高斯标注差,一般为1-1.5
			int flags // 计算方法。主要包括OPTFLOW_USE_INITIAL_FLOW和OPTFLOW_FARNEBACK_GAUSSIAN
			);
			*/
			calcOpticalFlowFarneback(prev_gray, gray, flowdata, 0.5, 3, 15, 3, 5, 1.2, 0); // 稠密光流是对整个图像的计算,所以实时性不好
			cvtColor(prev_gray, flowResult, COLOR_GRAY2BGR);//灰度图像转成RGB图像
			drawOpticalFlowHF(flowdata, flowResult, 10); // 绘制跟踪
			imshow("flow", flowResult);
			imshow("src6-11", frame);
			waitKey(100);
		}
		if (waitKey(1) == 27) break;
	}

	waitKey(0);
}

void drawOpticalFlowHF(const Mat &flowdata, Mat& image, int step)
{
	for (int row = 0; row < image.rows; row++)
	{
		for (int col = 0; col < image.cols; col++)
		{
			const Point2f fxy = flowdata.at<Point2f>(row, col);//flowdata保存的是每个像素点移动的距离
			if (fxy.x > 1 || fxy.y > 1) // x 或 y 方向移动了1个像素以上就表示该像素移动了
			{
				line(image, Point(col, row), Point(cvRound(col + fxy.x), cvRound(row + fxy.y)), Scalar(0, 255, 0), 2, 8, 0); // 移动轨迹
				//Point(col, row)为移动了的像素点的第一帧初始位置
				// Point(cvRound(col + fxy.x), cvRound(row + fxy.y))为移动了的像素点的第N帧实时位置
				circle(image, Point(col, row), 2, Scalar(0, 0, 255), -1); // 较一帧移动的像素点
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_41721222/article/details/83788382