2017-05-24 2 views
2

Ich kann bereits SIFT- oder SURF-Funktionen mit Lucas Kanade in OpenCV verfolgen, da Lucas Kanade spärliche Features auf irgendeine Weise verfolgt, aber ich versuche den in OpenCV implementierten optischen Ablaufalgorithmus von Farneback zu verwenden, um diese spärlichen Features zu verfolgen Das?Wie kann ich spärliche Features mit einem dichten optischen Flow-Ansatz wie Farnebacks verfolgen?

Realtime Dense Optical flow tracking

Bitte aktivieren Sie dieses Video:

Die Entwickler behaupten, dass sie die ausgewählten spärlichen Merkmale mit einem dichten Ansatz „Farneback“ eher als ein spärlichen Ansatz „Lucas-Kanade“ verfolgt. Wie haben die das getan?

+0

Bitte lesen Sie [on-Thema] (https://stackoverflow.com/help/on-topic). –

Antwort

2

Um eine Funktion mit einem dichten optischen Strömungsfeld verfolgt flow wie folgt durchgeführt werden kann:

// 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

Vielen Dank, ich teste Ihren Code. Eine letzte Frage: flowMat.at (iy, ix) * cv :: Point2f (w00, w00) -> Ist das Element weise Multiplikation oder ein Kreuzprodukt? weil das in opencv nicht funktioniert. – Akef

+0

Entschuldigung, ich habe gerade festgestellt, dass ein Kreuzprodukt für 2D-Vektoren keine Bedeutung hat, also nehme ich an, dass du eine elementweise Multiplikation meinst. – Akef

+0

Danke, es funktioniert irgendwie, aber ich musste ein paar Sachen reparieren – Akef

0

Es gibt eine Funktion in OpenCV, um genau das zu tun.

+1

Ich weiß über diese Funktion, Farnebacks Methode gibt ein Bewegungsfeld, das für jedes Pixel eine dichte Bedeutung ist, aber meine Frage ist, wie kann ich Farnebacks Funktion verwenden, um eine Reihe von spärlichen Schlüsselpunkten oder Features zu verfolgen. – Akef

Verwandte Themen