web-dev-qa-db-fra.com

Suivi OpenCV en utilisant le flux optique

Je l'utilise pour fonctionner comme base de mon algorithme de suivi.

    //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 prend en entrée le vecteur de points de l'image précédente et renvoie les points appropriés sur l'image suivante. Supposons que j'ai un pixel aléatoire (x, y) sur l'image précédente, comment puis-je calculer la position de ce pixel sur l'image suivante en utilisant la fonction de flux optique OpenCV?

18
Alex Hoppus

Au moment où vous écrivez, cv::goodFeaturesToTrack prend une image en entrée et produit un vecteur de points qu'elle juge "bon à suivre". Ceux-ci sont choisis en fonction de leur capacité à se démarquer de leur environnement et sont basés sur les coins Harris de l'image. Un tracker serait normalement initialisé en passant la première image à goodFeaturesToTrack et en obtenant un ensemble de fonctionnalités à suivre. Ces fonctionnalités pourraient ensuite être transmises à cv::calcOpticalFlowPyrLK comme les points précédents, avec l'image suivante dans la séquence et il produira les points suivants en sortie, qui deviendront alors des points d'entrée dans la prochaine itération.

Si vous souhaitez essayer de suivre un ensemble différent de pixels (plutôt que des fonctionnalités générées par cv::goodFeaturesToTrack ou une fonction similaire), fournissez-les simplement à cv::calcOpticalFlowPyrLK avec l'image suivante.

Très simplement, en code:

// 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;
}
29
Chris

cv :: calcOpticalFlowPyrLK (..) la fonction utilise des arguments:

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

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

code (partiel) le plus simple pour trouver le pixel dans l'image suivante:

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

Si le pixel a été trouvé avec succès status[0] == 1 et features_next[0] affichera les coordonnées du pixel dans l'image suivante. Les informations sur les valeurs se trouvent dans cet exemple: OpenCV/samples/cpp/lkdemo.cpp

1
MSeskas