File: kcf.cpp

package info (click to toggle)
opencv 3.2.0%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 238,480 kB
  • sloc: xml: 901,650; cpp: 703,419; lisp: 20,142; java: 17,843; python: 17,641; ansic: 603; cs: 601; sh: 516; perl: 494; makefile: 117
file content (194 lines) | stat: -rw-r--r-- 4,818 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*----------------------------------------------
 * Usage:
 * example_tracking_kcf <video_name>
 *
 * example:
 * example_tracking_kcf Bolt/img/%04.jpg
 * example_tracking_kcf faceocc2.webm
 *--------------------------------------------------*/

#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <cstring>

using namespace std;
using namespace cv;

class BoxExtractor {
public:
  Rect2d extract(Mat img);
  Rect2d extract(const std::string& windowName, Mat img, bool showCrossair = true);

  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 );
};

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
  BoxExtractor box;

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

  // set input video
  std::string video = argv[1];
  VideoCapture cap(video);

  Mat frame;

  // get bounding box
  cap >> frame;
  Rect2d roi=box.extract("tracker",frame);

  //quit if ROI was not selected
  if(roi.width==0 || roi.height==0)
    return 0;

  // 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);
}

Rect2d BoxExtractor::extract(const std::string& windowName, Mat img, bool showCrossair){

  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 );

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

    // draw cross air in the middle of bounding box
    if(showCrossair){
      // horizontal line
      line(
        params.image,
        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)),
        Scalar(255,0,0),2,1
      );

      // vertical line
      line(
        params.image,
        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)),
        Scalar(255,0,0),2,1
      );
    }

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