如何使用像Farneback这样的密集光流方法跟踪稀疏特征?

问题描述:

我可以使用OpenCV中实现的Lucas Kanade来跟踪SIFT或SURF的特性,因为Lucas Kanade会以任何方式跟踪稀疏特征,但是我尝试使用Farneback在OpenCV中实现的光流算法来跟踪那些稀疏特征,是否有算法那?如何使用像Farneback这样的密集光流方法跟踪稀疏特征?

Realtime Dense Optical flow tracking

请检查该视频:

开发者声称,他们使用密集办法“Farneback”而不是疏的方法“卢卡斯金出武雄”跟踪选定的稀疏特征。他们是如何做到的呢?

+0

请参阅[关于话题](https://stackoverflow.com/help/on-topic)。 –

要跟踪的特征具有致密光流场flow可以如下完成:

// read images  
cv:Mat prevImg = cv::imread(filename0); // image data at time t 
cv::Mat currImg = cv::imread(filename1); // image data at time t and t + 1 
cv::Mat flowMat; // storage for dese optical flow field 
std::vector<cv::Point2f> prevPoints; // points to be track 

// initialize points to track (example) 
prevPoints.push_back(cv::Point2f(50.3f, 30.f)); 
std::vector<cv::Point2f> currPoints(prevPoints.size()); // tracked point position 

// compute dense flow field (example) 
cv::calcOpticalFlowFarneback(prevImg, currImg, flowMat, 0.4, 1, 12, 2, 8, 1.2, 0); 

// track points based on dense optical flow field and bilinear interpolation 
for(unsigned int n = 0; n < prevPoints.size(); ++n) 
{ 
    float ix = floor(prevPoints[n].x); 
    float iy = floor(prevPoints[n].y); 
    float wx = prevPoints[n].x - ix; 
    float wy = prevPoints[n].y - iy; 
    float w00 = (1.f - wx) * (1.f - wy); 
    float w10 = (1.f - wx) * wy; 
    float w01 = wx * (1.f - wy); 
    float w11 = wx * wy; 
    if(prevPoints[n].x >= flowMat.cols - 1 || prevPoints[n].y >= flowMat.rows - 1) 
    { 
    // these points are out of the image roi and cannot be tracked. 
    currPoints[n] = prevPoints[n]; 
    } 
    else 
    { 
    /* 
    bilinear interpolation of the flow vector from the flow field at a given location. 
    The bilinear interpolation has to be applied since the points to track can be given at subpixel level 
    */ 
    currPoints[n] = prevPoints[n] 
       + flowMat.at<cv::Point2f>(iy, ix) * w00 
       + flowMat.at<cv::Point2f>(iy+1, ix) * w10 
       + flowMat.at<cv::Point2f>(iy, ix+1) * w01 
       + flowMat.at<cv::Point2f>(iy+1, ix+1) * w11; 
    } 
} 

} 
+0

非常感谢,我正在测试你的代码。最后一个问题:flowMat.at <:point2f>(iy,ix)* cv :: Point2f(w00,w00) - >这个元素是明智的乘法还是交叉乘积?因为这在opencv中不起作用。 – Akef

+0

对不起,我刚刚意识到,二维向量的交叉积没有意义,所以我假设你的意思是元素明智的乘法。 – Akef

+0

感谢它有点工作,但我不得不修理一些东西 – Akef

在OpenCV中有一个功能calcOpticalFlowFarneback()就是这么做的。

+1

我知道这个函数,Farneback的方法给出了对于每个像素都是密集的运动场,但是我的问题是我如何使用Farneback的函数来跟踪一组稀疏的关键点或特征。 – Akef