C++-OpenCV(7)-Lucas-Kanade光流算法

对于运动的视频,用Lucas-kanade进行跟踪,动态捕捉跟踪的目标。

C++-OpenCV(7)-Lucas-Kanade光流算法_第1张图片
代码如下:
 

string videoFileName = "videos/cycle.mp4";
	VideoCapture cap(videoFileName);

	int width = cap.get(CAP_PROP_FRAME_WIDTH);
	int height = cap.get(CAP_PROP_FRAME_HEIGHT);

	VideoWriter out("sparse-output.mp4", VideoWriter::fourcc('M', 'P', '4', 'V'), 20, Size(width, height));
	TermCriteria termcrit(TermCriteria::COUNT | TermCriteria::EPS, 10, 0.03);

	//读入视频的一帧图像 找到特征点存放在old_points中
	Mat old_frame;
	cap >> old_frame;
	Mat old_gray;
	cvtColor(old_frame, old_gray, COLOR_BGR2GRAY);
	vector old_points;
	vector status;
	vector err;
	vector new_points;
	vector good_new;
	vector good_old;
	vector colors;

	Point2f pt1, pt2;

	// Shi Tomasi corner detection
	goodFeaturesToTrack(old_gray,
		old_points,
		100,          // maxCorners
		0.3,          // qualityLevel
		7,            // minDistance
		Mat(),        // mask
		7             // blockSize
	);

	Mat display_frame;
	// Create a mask image for drawing the tracks
	Mat mask = Mat::zeros(old_frame.size().height, old_frame.size().width, CV_8UC3);
	int count = 0;
    Mat frame, frame_gray;

	//循环处理视频流文件
	while (1) {
		cap >> frame;
		if (frame.empty())
			cout << "over" << endl;
		cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
		count += 1;

		// 金字塔光流算法 在新的一帧中特征点的位置
		//第一帧图像,当前帧图像,特征点位置(前一帧中),新特征点位置
		//status 表示是否成功
		calcOpticalFlowPyrLK(old_gray, frame_gray, old_points, new_points,
			status, err,
			Size(15, 15), // winSize
			2,           // maxLevel
			termcrit     // criteria
		);
		
		/把轨迹给存起来 并绘制出来
		for (int i = 0; i < new_points.size(); i++)
		{
			if (status[i] == 1) {
				good_new.push_back(new_points[i]);//新找到的点复制到oldpoints里
				good_old.push_back(old_points[i]);
			}
		}

		getRandomColors(colors, new_points.size());

		// draw the tracks
		for (int j = 0; j < new_points.size(); j++)
		{
			pt1 = new_points[j];
			pt2 = old_points[j];
			line(mask, pt1, pt2, colors[j], 2, LINE_AA);
			circle(frame, pt1, 3, colors[j], -1);
		}
		
		//
		add(frame, mask, display_frame);
		//把绘制了视频帧轨迹的图像写成一个视频文件
		out.write(display_frame);

		if (count % 5 == 0) {
			imshow("Image", display_frame);
			waitKey(10);
		}
		if (count > 50)
			break;

		// Now update the previous frame and previous_points
		old_gray = frame_gray.clone();
		std::copy(new_points.begin(), new_points.end(), old_points.begin());
	}

	cap.release();
	out.release();

 

你可能感兴趣的:(opencv)