2012-03-14 17 views
14

Uso questo come funzione del mio algoritmo di tracciamento.Tracciamento OpenCV mediante flusso ottico

//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 prende vettore di punti dall'immagine precedente come input e restituisce punti appropriati sulla immagine successiva. Supponiamo di avere pixel casuali (x, y) nell'immagine precedente, come posso calcolare la posizione di questo pixel sull'immagine successiva utilizzando la funzione di flusso ottico OpenCV?

risposta

28

Come si scrive, cv::goodFeaturesToTrack prende un'immagine come input e produce un vettore di punti che ritiene "buono da tracciare". Questi sono scelti in base alla loro capacità di distinguersi da ciò che li circonda e sono basati sugli angoli di Harris nell'immagine. Un tracker verrebbe normalmente inizializzato passando la prima immagine a goodFeaturesToTrack e ottenendo un set di funzionalità da tracciare. Queste caratteristiche possono essere passate a cv::calcOpticalFlowPyrLK come i punti precedenti, insieme all'immagine successiva nella sequenza e produrrà i punti successivi come output, che quindi diventeranno punti di input nella successiva iterazione.

Se si desidera provare a tracciare un diverso set di pixel (anziché le funzioni generate da cv::goodFeaturesToTrack o una funzione simile), fornire semplicemente questi a cv::calcOpticalFlowPyrLK insieme all'immagine successiva.

Molto semplicemente, in codice:

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

Si noti che si esegue solo il rilevamento delle funzioni per una volta. Ho testato questo codice. Ho trovato solo le caratteristiche rilevate sulla prima immagine che possono essere monitorate. Se tutte queste funzionalità vanno oltre l'immagine, non ci sarebbe alcuna funzione da tracciare. Ho bisogno di usare il flusso ottico per la costruzione 3D. Allora come possiamo rintracciare continuamente le vecchie funzionalità e nel frattempo aggiungere nuove funzionalità di immagine? Grazie. – Shiyu

+1

Sì, si rilevano solo le funzioni con 'goodFeaturesToTrack', quindi il metodo del flusso ottico semplicemente le tiene traccia. Se si desidera mantenere un certo numero di funzionalità in ciascun fotogramma, è necessario rilevare il numero di funzioni che sono state tracciate correttamente nel fotogramma corrente e quindi provare a rilevare quelle aggiuntive da tracciare sul fotogramma successivo. Un'alternativa sarebbe quella di rilevare le caratteristiche in ogni fotogramma e quindi calcolare i descrittori e abbinare tali descrittori utilizzando le funzioni su [questa pagina] (http://opencv.itseez.com/modules/features2d/doc/features2d.html). – Chris

+0

Se hai bisogno di maggiori dettagli, sarebbe meglio fare una nuova domanda. – Chris

1

cv :: calcOpticalFlowPyrLK (..) funzione utilizza argomenti:

cv :: calcOpticalFlowPyrLK (prev_gray, curr_gray, features_prev, features_next, lo stato, err);

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

semplice codice (parziale) per trovare pixel nel frame successivo:

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

Se pixel è stato trovato con successo status[0] == 1 e features_next[0] mostrerà coordinate di pixel nel fotogramma successivo. Informazioni sul valore possono essere trovate in questo esempio: OpenCV/samples/cpp/lkdemo.cpp

Problemi correlati