2012-03-14 92 views
14

我使用它作为我的跟踪算法的基础。使用光流的OpenCV跟踪

//1. detect the features 
    cv::goodFeaturesToTrack(gray_prev, // the image 
    features, // the output detected features 
    max_count, // the maximum number of features 
    qlevel,  // quality level 
    minDist); // min distance between two features 

    // 2. track features 
    cv::calcOpticalFlowPyrLK(
    gray_prev, gray, // 2 consecutive images 
    points_prev, // input point positions in first im 
    points_cur, // output point positions in the 2nd 
    status, // tracking success 
    err);  // tracking error 

cv::calcOpticalFlowPyrLK取点的矢量来自先前图像作为输入,并且对下一个图像返回适当点。假设在前一个图像上有随机像素(x,y),如何使用OpenCV光流功能计算下一个图像上该像素的位置?

回答

28

正如你所写,cv::goodFeaturesToTrack将图像作为输入并产生一个它认为“很好跟踪”的点向量。这些选择是基于他们脱离周围环境的能力,并基于图像中的哈里斯角。跟踪器通常会通过将第一个图像传递给goodFeaturesToTrack并获取一组要跟踪的功能来初始化。然后这些特征可以作为前面的点传递给cv::calcOpticalFlowPyrLK,以及序列中的下一个图像,它将产生下一个点作为输出,然后在下一次迭代中将成为输入点。

如果您想尝试跟踪不同的像素组(而不是cv::goodFeaturesToTrack或类似功能生成的功能),那么只需将这些图像与下一张图像一起提供给cv::calcOpticalFlowPyrLK即可。

很简单,在代码:

// Obtain first image and set up two feature vectors 
cv::Mat image_prev, image_next; 
std::vector<cv::Point> features_prev, features_next; 

image_next = getImage(); 

// Obtain initial set of features 
cv::goodFeaturesToTrack(image_next, // the image 
    features_next, // the output detected features 
    max_count, // the maximum number of features 
    qlevel,  // quality level 
    minDist  // min distance between two features 
); 

// Tracker is initialised and initial features are stored in features_next 
// Now iterate through rest of images 
for(;;) 
{ 
    image_prev = image_next.clone(); 
    feature_prev = features_next; 
    image_next = getImage(); // Get next image 

    // Find position of feature in new image 
    cv::calcOpticalFlowPyrLK(
     image_prev, image_next, // 2 consecutive images 
     points_prev, // input point positions in first im 
     points_next, // output point positions in the 2nd 
     status, // tracking success 
     err  // tracking error 
    ); 

    if (stopTracking()) break; 
} 
+1

我注意到你只做一次特征检测。我测试了这个代码。我发现只有在第一张图像上检测到的功能才能被追踪。如果所有这些功能都超出了图像范围,那么就无法跟踪。我需要使用光流进行3D建设。那么我们如何能够持续跟踪旧功能并同时添加新的图像功能?谢谢。 – Shiyu 2012-04-15 02:53:27

+1

是的,你只能用'goodFeaturesToTrack'检测特征,然后光流方法只是跟踪它们。如果要在每个帧中保留一定数量的功能,则必须检测到当前帧有多少功能被成功跟踪,然后尝试检测追加到下一帧的附加功能。另一种方法是在每个帧中检测特征,然后计算描述符并通过使用[本页]上的函数来匹配这些描述符(http://opencv.itseez.com/modules/features2d/doc/features2d.html)。 – Chris 2012-04-16 08:37:32

+0

如果你需要更多的细节,最好问一个新的问题。 – Chris 2012-04-16 08:37:51

1

CV :: calcOpticalFlowPyrLK(..)函数使用参数:

CV :: calcOpticalFlowPyrLK(prev_gray,curr_gray,features_prev,features_next,地位,呃);

cv::Mat prev_gray, curr_gray; 
std::vector<cv::Point2f> features_prev, features_next; 
std::vector<uchar> status; 
std::vector<float> err; 

最简单的(部分)代码,找出像素下一帧:

features_prev.push_back(cv::Point(4, 5)); 
cv::calcOpticalFlowPyrLK(prev_gray, curr_gray, features_prev, features_next, status, err); 

如果像素被成功找到status[0] == 1features_next[0]将显示像素的坐标在下一帧。价值信息可以在这个例子中找到:OpenCV/samples/cpp/lkdemo.cpp