2012-03-14 25 views
14

Bunu, izleme algoritmamın bir temeli olarak kullanmak için kullanıyorum.Optik akış kullanarak OpenCV izleme

//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 giriş olarak bir önceki görüntü noktalarının vector alır ve bir sonraki resim üzerinde uygun noktaları döndürür. Bir önceki resimde rastgele piksel (x, y) olduğunu varsayalım, OpenCV optik akış fonksiyonunu kullanarak bir sonraki resimde bu pikselin konumunu nasıl hesaplayabilirim?

cevap

28

Yazarken, cv::goodFeaturesToTrack bir görüntüyü giriş olarak alır ve "izlemek için iyi" olduğunu düşündüğü noktaların bir vektörünü üretir. Bunlar çevrelerinden uzak durma yeteneklerine göre seçilir ve görüntüdeki Harris köşelerine dayanır. Bir izleyici normalde ilk görüntüyü goodFeaturesToTrack'e geçirerek ve izlenmek üzere bir dizi özellik elde ederek başlatılacaktır. Bu özellikler daha sonra cv::calcOpticalFlowPyrLK'a önceki noktalarla birlikte, sıradaki sonraki görüntü ile birlikte geçirilebilir ve çıktı olarak bir sonraki noktaları üretecek ve ardından sonraki iterasyonda girdi noktaları haline gelecektir. Farklı bir piksel kümesini (cv::goodFeaturesToTrack veya benzeri bir işlev tarafından oluşturulan özellikler yerine) izlemeyi denemek isterseniz, cv::calcOpticalFlowPyrLK ürününü bir sonraki görüntü ile birlikte sağlayın. Basitçe, kodda

:

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

Sadece bir defada özellik tespiti yaptığınızı görüyorum. Bu kodu test ettim. Sadece ilk görüntüde tespit edilen özelliklerin izlenebildiğini buldum. Tüm bu özellikler görüntünün ötesine geçerse, izlenmesi gereken bir özellik yoktur. 3D konstrüksiyon için optik akış kullanmam gerekiyor. O zaman eski özellikleri sürekli olarak nasıl izleyebiliriz ve bu arada yeni görüntü özellikleri ekleyebiliriz? Teşekkürler. – Shiyu

+1

Evet, yalnızca 'goodFeaturesToTrack' ile özellikleri algılarsınız, daha sonra optik akış yöntemi bunları izler. Her bir karede belirli sayıda özelliği korumak istiyorsanız, mevcut kareye kaç tane özelliğin başarılı bir şekilde izlendiğini tespit etmeli ve ardından bir sonraki kareye izlenecek ekleri tespit etmeye çalışmalısınız. Bir alternatif, her karedeki özellikleri tespit etmek ve sonra tanımlayıcıları hesaplamak ve bu tanımlayıcıları [bu sayfadaki] işlevleri kullanarak eşleştirmektir (http://opencv.itseez.com/modules/features2d/doc/features2d.html). – Chris

+0

Daha fazla ayrıntıya ihtiyacınız varsa, yeni bir soru sormak daha iyi olur. – Chris

1

cv :: calcOpticalFlowPyrLK (..) fonksiyon argümanları kullanır: (

cv :: calcOpticalFlowPyrLK prev_gray, curr_gray, features_prev, features_next, statü,) err;

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

sonraki çerçevede piksel bulmak en kolay (kısmi) kod:

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

piksel başarıyla status[0] == 1 ve features_next[0] sonraki çerçevede piksel koordinatlarını gösterir bulunmuştur edin. Değer bilgisi şu örnekte bulunabilir: OpenCV/samples/cpp/lkdemo.cpp