2012-03-14 44 views
14

Tôi sử dụng tính năng này để hoạt động như một cơ sở của thuật toán theo dõi của mình.Theo dõi OpenCV bằng luồng quang

//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 lấy vector điểm từ hình ảnh trước làm đầu vào và trả về các điểm thích hợp trên hình ảnh tiếp theo. Giả sử tôi có pixel ngẫu nhiên (x, y) trên hình ảnh trước đó, làm cách nào tôi có thể tính toán vị trí của pixel này trên hình ảnh tiếp theo bằng chức năng lưu lượng quang OpenCV?

Trả lời

28

Khi bạn viết, cv::goodFeaturesToTrack lấy hình ảnh làm đầu vào và tạo ra một vectơ các điểm mà nó cho là "tốt để theo dõi". Chúng được chọn dựa trên khả năng của chúng để nổi bật so với môi trường xung quanh, và dựa trên góc Harris trong hình ảnh. Trình theo dõi thường được khởi tạo bằng cách chuyển hình ảnh đầu tiên đến goodFeaturesToTrack và thu thập một tập hợp các tính năng để theo dõi. Các tính năng này sau đó có thể được chuyển đến cv::calcOpticalFlowPyrLK như các điểm trước đó, cùng với hình ảnh tiếp theo trong chuỗi và nó sẽ tạo ra các điểm tiếp theo dưới dạng đầu ra, sau đó trở thành điểm đầu vào trong lần lặp tiếp theo.

Nếu bạn muốn thử theo dõi một tập hợp pixel khác (chứ không phải là các tính năng được tạo bởi cv::goodFeaturesToTrack hoặc chức năng tương tự), sau đó chỉ cần cung cấp các ảnh này cv::calcOpticalFlowPyrLK cùng với hình ảnh tiếp theo.

Rất đơn giản, trong mã:

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

Tôi nhận thấy bạn chỉ thực hiện phát hiện tính năng một lần. Tôi đã thử nghiệm mã này. Tôi chỉ tìm thấy các tính năng được phát hiện trên hình ảnh đầu tiên có thể được theo dõi. Nếu tất cả các tính năng này vượt quá hình ảnh, sẽ không có tính năng nào để theo dõi. Tôi cần sử dụng luồng quang học để xây dựng 3D. Sau đó, làm thế nào chúng tôi có thể liên tục theo dõi các tính năng cũ và trong khi chờ đợi thêm các tính năng hình ảnh mới? Cảm ơn. – Shiyu

+1

Có, bạn chỉ phát hiện các tính năng với 'goodFeaturesToTrack', sau đó phương pháp lưu lượng quang đơn giản theo dõi chúng. Nếu bạn muốn duy trì một số tính năng nhất định trong mỗi khung hình, bạn sẽ phải phát hiện có bao nhiêu tính năng được theo dõi thành công đến khung hiện tại và sau đó tìm cách phát hiện các tính năng bổ sung được theo dõi tới khung tiếp theo. Một cách khác là phát hiện các tính năng trong mỗi khung hình, sau đó tính toán các bộ mô tả và so khớp các mô tả đó bằng cách sử dụng các hàm trên [trang này] (http://opencv.itseez.com/modules/features2d/doc/features2d.html). – Chris

+0

Nếu bạn cần thêm chi tiết, sẽ tốt hơn nếu bạn đặt câu hỏi mới. – Chris

1

cv :: calcOpticalFlowPyrLK (..) chức năng sử dụng đối số:

cv :: calcOpticalFlowPyrLK (prev_gray, curr_gray, features_prev, features_next, tình trạng, err);

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

đơn giản nhất (một phần) mã để tìm điểm ảnh trong khung tiếp theo:

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

Nếu điểm ảnh được thành công tìm thấy status[0] == 1features_next[0] sẽ hiển thị tọa độ của điểm ảnh trong khung tiếp theo. Thông tin giá trị có thể được tìm thấy trong ví dụ này: OpenCV/samples/cpp/lkdemo.cpp

Các vấn đề liên quan