2012-03-14 19 views
14

Lo uso para funciones como base de mi algoritmo de seguimiento.Seguimiento de OpenCV usando flujo óptico

//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 toma vector de puntos de la imagen anterior como entrada y devuelve los puntos apropiados en la siguiente imagen. Supongamos que tengo un píxel aleatorio (x, y) en la imagen anterior, ¿cómo puedo calcular la posición de este píxel en la siguiente imagen usando la función de flujo óptico OpenCV?

Respuesta

28

Al escribir, cv::goodFeaturesToTrack toma una imagen como entrada y produce un vector de puntos que considera "bueno de seguir". Estos se eligen en función de su capacidad para destacarse de su entorno y se basan en las esquinas de Harris en la imagen. Normalmente, un rastreador se inicializa al pasar la primera imagen a goodFeaturesToTrack y obtener un conjunto de características para rastrear. Estas características podrían pasarse a cv::calcOpticalFlowPyrLK como los puntos anteriores, junto con la siguiente imagen en la secuencia y producirá los siguientes puntos como salida, que luego se convertirán en puntos de entrada en la siguiente iteración.

Si desea tratar de rastrear un conjunto de píxeles diferente (en lugar de las características generadas por cv::goodFeaturesToTrack o una función similar), simplemente bríndelas a cv::calcOpticalFlowPyrLK junto con la imagen siguiente.

Muy simplemente, en código:

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

Me di cuenta de que solo tiene detección de características por una vez. He probado este código. Descubrí que solo se pueden rastrear las características detectadas en la primera imagen. Si todas estas características van más allá de la imagen, no habría ninguna función para seguir. Necesito usar flujo óptico para construcción en 3D. Entonces, ¿cómo podemos seguir continuamente las funciones antiguas y, mientras tanto, agregar nuevas características de imagen? Gracias. – Shiyu

+1

Sí, solo detecta características con 'goodFeaturesToTrack', luego el método de flujo óptico simplemente las rastrea. Si desea mantener un número determinado de características en cada cuadro, deberá detectar cuántas características se rastrearon con éxito en el cuadro actual y luego intentar detectar otras para seguir en el siguiente cuadro. Una alternativa sería detectar características en cada cuadro, y luego calcular descriptores y unir esos descriptores mediante el uso de funciones en [esta página] (http://opencv.itseez.com/modules/features2d/doc/features2d.html). – Chris

+0

Si necesita más detalles, sería mejor hacer una nueva pregunta. – Chris

1

cv :: calcOpticalFlowPyrLK (..) función utiliza argumentos:

cv :: calcOpticalFlowPyrLK (prev_gray, curr_gray, features_prev, features_next, estado, errar);

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

más simple código (parcial) para encontrar píxeles en el siguiente cuadro:

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

Si píxeles ésta se ha encontrado status[0] == 1 y features_next[0] mostrará las coordenadas del píxel en el próximo marco. La información del valor se puede encontrar en este ejemplo: OpenCV/samples/cpp/lkdemo.cpp

Cuestiones relacionadas