summaryrefslogtreecommitdiffstats
path: root/SD-VBS/common/toolbox/lagrcv/calcOpticalFlowPyrLK.cc
blob: d4be5ffde920716394831008fa80c0ba2411278d (plain) (blame)
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

/* compile with 
   mex calcOpticalFlowPyrLK.cc -I/usr/local/opencv/include -L/usr/local/opencv/lib -lcxcore -lcv
*/

#include "mex.h"
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include <stdio.h>
#include <math.h>

#define WIN_SIZE 8
#define PYR_LEVELS 3

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
  // usage: [ newpoints status pyr1 ] = 
  //     calcOpticalFlowPyrLK(im1,im2,oldpoints,pyr1)
  // images must be single-channel, 8-bit
  // DO NOT PASS SAME IMAGE IN TWICE!

  char *im1_ptr = (char*)mxGetPr(prhs[0]);
  char *im2_ptr = (char*)mxGetPr(prhs[1]);
  const int *imdims = mxGetDimensions(prhs[0]);
  IplImage *pyr1 = 0, *pyr2 = 0;
  int flags = 0;
  bool clearPyr1 = false;
  int max_iter;

  max_iter=30;

  /* images */
  IplImage *im1 = 
    cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1);
  IplImage *im2 = 
    cvCreateImageHeader(cvSize(imdims[0], imdims[1]), IPL_DEPTH_8U, 1);
  im1->imageData = im1_ptr;
  im2->imageData = im2_ptr;

  /* allocate pyramids */
  pyr1 = cvCreateImageHeader(cvSize(imdims[0],imdims[1]), IPL_DEPTH_8U, 1);
  pyr2 = cvCreateImageHeader(cvSize(imdims[0],imdims[1]), IPL_DEPTH_8U, 1);
  // reuse pyramid if given
  if (nrhs > 3) {
    pyr1->imageData = (char*)mxGetPr(prhs[3]);
    flags |= CV_LKFLOW_PYR_A_READY;
  } else {
    clearPyr1 = true;
    cvCreateData(pyr1);
  }

  // pyr2 will be reused, so allocate in return value
  plhs[2] = mxCreateNumericMatrix(imdims[0], imdims[1], mxUINT8_CLASS, mxREAL);
  pyr2->imageData = (char*)mxGetPr(plhs[2]);

  /* coordinate arrays */
  CvPoint2D32f *oldpoints = (CvPoint2D32f*)mxGetPr(prhs[2]);
  const int *pointsdim = mxGetDimensions(prhs[2]);
  int npoints = pointsdim[1];
  plhs[0] = mxCreateNumericMatrix(2, npoints, mxSINGLE_CLASS, mxREAL);
  CvPoint2D32f *newpoints = (CvPoint2D32f*)mxGetPr(plhs[0]);

  /* status array */
  plhs[1] = mxCreateNumericMatrix(1, npoints, mxUINT8_CLASS, mxREAL);
  char *status = (char*)mxGetPr(plhs[1]);
  
  cvCalcOpticalFlowPyrLK(im1, im2, 
                         pyr1, pyr2,
                         oldpoints, newpoints, npoints,
                         cvSize(WIN_SIZE, WIN_SIZE), PYR_LEVELS,
                         status, 
                         NULL,
                         cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,max_iter,0.03),
                         flags
                         );
  if (clearPyr1) 
    cvReleaseImage(&pyr1);
}