2012-03-14 5 views
14

나는 이것을 내 추적 알고리즘의 기본 기능으로 사용합니다.옵티컬 플로우를 사용한 OpenCV 추적

//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 입력으로 이전 이미지에서 포인트의 벡터를 받아, 다음 이미지에 적절한 포인트를 반환합니다. 이전 이미지에 임의의 픽셀 (x, y)이 있다고 가정하면 OpenCV 옵티컬 플로우 함수를 사용하여 다음 이미지에서이 픽셀의 위치를 ​​어떻게 계산할 수 있습니까?

답변

28

쓸 때, cv::goodFeaturesToTrack은 이미지를 입력 받아 "추적하기 좋은"것으로 간주되는 점의 벡터를 생성합니다. 이들은 주변 환경에서 눈에 띄는 능력에 따라 선택되며 이미지의 해리스 코너를 기반으로합니다. 트래커는 일반적으로 첫 번째 이미지를 goodFeaturesToTrack에 전달하고 추적 할 피쳐 세트를 얻음으로써 초기화됩니다. 그런 다음이 기능을 시퀀스의 다음 이미지와 함께 이전 포인트로 cv::calcOpticalFlowPyrLK에 전달할 수 있으며 다음 포인트를 출력으로 생성하고 다음 반복에서 입력 포인트가됩니다.

cv::goodFeaturesToTrack 또는 유사한 기능으로 생성 된 기능이 아닌 다른 픽셀 세트를 추적하려는 경우 다음 이미지와 함께 cv::calcOpticalFlowPyrLK에 제공하면됩니다. 아주 간단하게, 코드

:

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

한 번만 기능을 감지합니다. 나는이 코드를 테스트했다. 첫 번째 이미지에서 탐지 된 기능 만 추적 할 수 있음을 발견했습니다. 이러한 모든 기능이 이미지를 넘어서는 경우 추적 할 기능이 없습니다. 3D 구축에 광학 흐름을 사용해야합니다. 그러면 이전 기능을 계속 추적하고 그 동안 새로운 이미지 기능을 추가하려면 어떻게해야합니까? 감사. – Shiyu

+1

예, 'goodFeaturesToTrack' 기능 만 검색하면 옵티컬 플로 방식으로 간단히 추적 할 수 있습니다. 각 프레임에 특정 수의 기능을 유지하려면 현재 프레임에 대해 얼마나 많은 기능을 추적했는지 감지 한 다음 추가 기능을 탐지하여 다음 프레임으로 추적해야합니다. 대안은 모든 프레임에서 기능을 탐지 한 다음 [이 페이지] (http://opencv.itseez.com/modules/features2d/doc/features2d.html)의 기능을 사용하여 설명자를 계산하고 해당 설명자를 일치시키는 것입니다. – Chris

+0

자세한 내용이 필요하면 새로운 질문을하는 것이 좋습니다. – Chris

1

이력서 :: calcOpticalFlowPyrLK (..) 함수는 인수를 사용합니다 (

이력서 :: calcOpticalFlowPyrLK을 prev_gray, curr_gray, features_prev, features_next, 상태, 오류);

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

다음 프레임에서 픽셀을 찾을 수있는 간단한 (부분) 코드 :

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

픽셀이 성공적으로 status[0] == 1features_next[0] 다음 프레임에서 픽셀의 좌표를 표시합니다 발견 된 경우. 다음 예에서 값 정보를 찾을 수 있습니다. OpenCV/samples/cpp/lkdemo.cpp

관련 문제