kcf.cpp 4.71 KB
Newer Older
1 2
/*----------------------------------------------
 * Usage:
3
 * example_tracking_kcf <video_name>
4 5 6 7 8 9
 *
 * example:
 * example_tracking_kcf Bolt/img/%04.jpg
 * example_tracking_kcf faceocc2.webm
 *--------------------------------------------------*/

10
#include <opencv2/core/utility.hpp>
11
#include <opencv2/tracking.hpp>
12 13
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
14 15 16 17 18 19 20 21 22
#include <iostream>
#include <cstring>

using namespace std;
using namespace cv;

class BoxExtractor {
public:
  Rect2d extract(Mat img);
23
  Rect2d extract(const std::string& windowName, Mat img, bool showCrossair = true);
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38

  struct handlerT{
    bool isDrawing;
    Rect2d box;
    Mat image;

    // initializer list
    handlerT(): isDrawing(false) {};
  }params;

private:
  static void mouseHandler(int event, int x, int y, int flags, void *param);
  void opencv_mouse_callback( int event, int x, int y, int , void *param );
};

39 40 41 42 43 44 45 46 47 48 49 50 51
int main( int argc, char** argv ){
  // show help
  if(argc<2){
    cout<<
      " Usage: example_tracking_kcf <video_name>\n"
      " examples:\n"
      " example_tracking_kcf Bolt/img/%04.jpg\n"
      " example_tracking_kcf faceocc2.webm\n"
      << endl;
    return 0;
  }

  // ROI selector
52 53 54 55 56
  BoxExtractor box;

  // create the tracker
  Ptr<Tracker> tracker = Tracker::create( "KCF" );

57
  // set input video
58
  std::string video = argv[1];
59
  VideoCapture cap(video);
60 61 62 63 64

  Mat frame;

  // get bounding box
  cap >> frame;
65 66 67 68 69
  Rect2d roi=box.extract("tracker",frame);

  //quit if ROI was not selected
  if(roi.width==0 || roi.height==0)
    return 0;
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

  // initialize the tracker
  tracker->init(frame,roi);

  // do the tracking
  printf("Start the tracking process, press ESC to quit.\n");
  for ( ;; ){
    // get frame from the video
    cap >> frame;

    // stop the program if no more images
    if(frame.rows==0 || frame.cols==0)
      break;

    // update the tracking result
    tracker->update(frame,roi);

    // draw the tracked object
    rectangle( frame, roi, Scalar( 255, 0, 0 ), 2, 1 );

    // show image with the tracked object
    imshow("tracker",frame);

    //quit on ESC button
    if(waitKey(1)==27)break;
  }

}

void BoxExtractor::mouseHandler(int event, int x, int y, int flags, void *param){
    BoxExtractor *self =static_cast<BoxExtractor*>(param);
    self->opencv_mouse_callback(event,x,y,flags,param);
}

void BoxExtractor::opencv_mouse_callback( int event, int x, int y, int , void *param ){
    handlerT * data = (handlerT*)param;
    switch( event ){
      // update the selected bounding box
      case EVENT_MOUSEMOVE:
        if( data->isDrawing ){
          data->box.width = x-data->box.x;
          data->box.height = y-data->box.y;
        }
      break;

      // start to select the bounding box
      case EVENT_LBUTTONDOWN:
        data->isDrawing = true;
        data->box = cvRect( x, y, 0, 0 );
      break;

      // cleaning up the selected bounding box
      case EVENT_LBUTTONUP:
        data->isDrawing = false;
        if( data->box.width < 0 ){
          data->box.x += data->box.width;
          data->box.width *= -1;
        }
        if( data->box.height < 0 ){
          data->box.y += data->box.height;
          data->box.height *= -1;
        }
      break;
    }
}

Rect2d BoxExtractor::extract(Mat img){
  return extract("Bounding Box Extractor", img);
}

140
Rect2d BoxExtractor::extract(const std::string& windowName, Mat img, bool showCrossair){
141 142 143 144 145 146 147 148 149 150 151 152 153

  int key=0;

  // show the image and give feedback to user
  imshow(windowName,img);
  printf("Select an object to track and then press SPACE/BACKSPACE/ENTER button!\n");

  // copy the data, rectangle should be drawn in the fresh image
  params.image=img.clone();

  // select the object
  setMouseCallback( windowName, mouseHandler, (void *)&params );

154
  // end selection process on SPACE (32) BACKSPACE (27) or ENTER (13)
155 156 157 158
  while(!(key==32 || key==27 || key==13)){
    // draw the selected object
    rectangle(
      params.image,
159
      params.box,
160 161 162
      Scalar(255,0,0),2,1
    );

163 164 165 166 167
    // draw cross air in the middle of bounding box
    if(showCrossair){
      // horizontal line
      line(
        params.image,
Kurnianggoro's avatar
Kurnianggoro committed
168 169
        Point((int)params.box.x,(int)(params.box.y+params.box.height/2)),
        Point((int)(params.box.x+params.box.width),(int)(params.box.y+params.box.height/2)),
170 171 172 173 174 175
        Scalar(255,0,0),2,1
      );

      // vertical line
      line(
        params.image,
Kurnianggoro's avatar
Kurnianggoro committed
176 177
        Point((int)(params.box.x+params.box.width/2),(int)params.box.y),
        Point((int)(params.box.x+params.box.width/2),(int)(params.box.y+params.box.height)),
178 179 180 181
        Scalar(255,0,0),2,1
      );
    }

182 183 184 185 186 187 188 189 190 191 192 193
    // show the image bouding box
    imshow(windowName,params.image);

    // reset the image
    params.image=img.clone();

    //get keyboard event
    key=waitKey(1);
  }


  return params.box;
194
}