C++-OpenCV(7)-Lucas-Kanade光流算法
对于运动的视频,用Lucas-kanade进行跟踪,动态捕捉跟踪的目标。

代码如下:
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<Point2f> old_points;
vector<uchar> status;
vector<float> err;
vector<Point2f> new_points;
vector<Point2f> good_new;
vector<Point2f> good_old;
vector<Scalar> 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();

浙公网安备 33010602011771号