2015-05-06 67 views
1

如何在lkdemo.pp(klt光流跟蹤器opencv示例)源代碼中添加基於roi的選擇? 我想在第一幀選擇roi,並在roi中選擇追蹤特徵點。基於ROI的KLT光學跟蹤器opencv

#include "opencv2/video/tracking.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include "opencv2/highgui/highgui.hpp" 

#include <iostream> 
#include <ctype.h> 

using namespace cv; 
using namespace std; 

static void help() 
{ 
    // print a welcome message, and the OpenCV version 
    cout << "\nThis is a demo of Lukas-Kanade optical flow lkdemo(),\n" 
      "Using OpenCV version " << CV_VERSION << endl; 

} 

Point2f point; 
bool addRemovePt = false; 

static void onMouse(int event, int x, int y, int , void*) 
{ 
    if(event == CV_EVENT_LBUTTONDOWN) 
    { 
     point = Point2f((float)x, (float)y); 
     addRemovePt = true; 
    } 
} 

int main(int argc, char** argv) 
{ 
    help(); 

    VideoCapture cap(CV_CAP_ANY); 
    TermCriteria termcrit(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 20, 0.03); 
    Size subPixWinSize(10,10), winSize(61,61); 

    const int MAX_COUNT = 500; 
    bool needToInit = false; 
    bool nightMode = false; 

    //if(argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0]))) 
     //cap.open(argc == 2 ? argv[1][0] - '0' : 0); 
    //else if(argc == 2) 
     //cap.open(argv[1]); 

    if(!cap.isOpened()) 
    { 
     cout << "Could not initialize capturing...\n"; 
     return 0; 
    } 

    namedWindow("LK Demo", 1); 
    setMouseCallback("LK Demo", onMouse, 0); 

    Mat gray, prevGray, image; 
    vector<Point2f> points[2]; 

    for(;;) 
    { 
     Mat frame; 
     cap >> frame; 
     if(frame.empty()) 
      break; 

     frame.copyTo(image); 
     cvtColor(image, gray, COLOR_RGB2GRAY); 

     if(nightMode) 
      image = Scalar::all(0); 

     if(needToInit) 
     { 
      // automatic initialization 
      goodFeaturesToTrack(gray, points[1], MAX_COUNT, 0.01, 10, Mat(), 3, 0, 0.04); 
      cornerSubPix(gray, points[1], subPixWinSize, Size(-1,-1), termcrit); 
      addRemovePt = false; 
     } 
     else if(!points[0].empty()) 
     { 
      vector<uchar> status; 
      vector<float> err; 
      if(prevGray.empty()) 
       gray.copyTo(prevGray); 
      calcOpticalFlowPyrLK(prevGray, gray, points[0], points[1], status, err, winSize,10, termcrit, 0, 0.001); 
      size_t i, k; 
      for(i = k = 0; i < points[1].size(); i++) 
      { 
       if(addRemovePt) 
       { 
        if(norm(point - points[1][i]) <= 5) 
        { 
         addRemovePt = false; 
         continue; 
        } 
       } 

       if(!status[i]) 
        continue; 

       points[1][k++] = points[1][i]; 
       circle(image, points[1][i], 3, Scalar(0,255,0), -1, 8); 
      } 
      points[1].resize(k); 
     } 

     if(addRemovePt && points[1].size() < (size_t)MAX_COUNT) 
     { 
      vector<Point2f> tmp; 
      tmp.push_back(point); 
      cornerSubPix(gray, tmp, winSize, cvSize(-1,-1), termcrit); 
      points[1].push_back(tmp[0]); 
      addRemovePt = false; 
     } 

     needToInit = false; 
     imshow("LK Demo", image); 

     char c = (char)waitKey(10); 
     if(c == 27) 
      break; 
     switch(c) 
     { 
     case 'r': 
      needToInit = true; 
      break; 
     case 'c': 
      points[0].clear(); 
      points[1].clear(); 
      break; 
     case 'n': 
      nightMode = !nightMode; 
      break; 
     } 

     std::swap(points[1], points[0]); 
     cv::swap(prevGray, gray); 
    } 

    return 0; 
} 

回答

0

以下是我在這些情況下使用:

void SelectNewTemplate(int event, int posx, int posy, int flags, void* userdata) 
{ 
    if(event == EVENT_MBUTTONDOWN) 
    { 
     waitKey(); 
    } 
    if(event == CV_EVENT_LBUTTONDOWN) 
    { 
     x1pt = posx; 
     y1pt = posy; 
    } 
    if(event == CV_EVENT_LBUTTONUP) 
    { 
     x2pt = posx; 
     y2pt = posy; 

     Rect newTemp(x1pt, y1pt, (x2pt - x1pt), (y2pt - y1pt)); 
     Mat imgROI = frame(newTemp); 
    } 
} 

用法:暫停使用鼠標中鍵,然後離開CLIC,拖動視頻和放手,按任意鍵繼續下去。


之後,您可以計算您的新投資回報圖像上的功能:imgROI

希望有幫助, Thomas