220 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Mathematica
		
	
	
	
	
	
			
		
		
	
	
			220 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Mathematica
		
	
	
	
	
	
#! /usr/bin/env octave
 | 
						|
 | 
						|
printf("OpenCV Octave version of lkdemo\n");
 | 
						|
 | 
						|
## import the necessary things for OpenCV
 | 
						|
cv;
 | 
						|
highgui;
 | 
						|
 | 
						|
#############################################################################
 | 
						|
## some "constants"
 | 
						|
 | 
						|
win_size = 10;
 | 
						|
MAX_COUNT = 500;
 | 
						|
 | 
						|
#############################################################################
 | 
						|
## some "global" variables
 | 
						|
 | 
						|
global g;
 | 
						|
 | 
						|
g.image = [];
 | 
						|
g.pt = [];
 | 
						|
g.add_remove_pt = false;
 | 
						|
g.flags = 0;
 | 
						|
g.night_mode = false;
 | 
						|
g.need_to_init = true;
 | 
						|
 | 
						|
g
 | 
						|
 | 
						|
#############################################################################
 | 
						|
## the mouse callback
 | 
						|
 | 
						|
## the callback on the trackbar
 | 
						|
function on_mouse (event, x, y, flags, param)
 | 
						|
  global g;
 | 
						|
  global cv;
 | 
						|
  global highgui;
 | 
						|
 | 
						|
  if (swig_this(g.image) == 0)
 | 
						|
    ## not initialized, so skip
 | 
						|
    return;
 | 
						|
  endif
 | 
						|
 | 
						|
  if (g.image.origin != 0)
 | 
						|
    ## different origin
 | 
						|
    y = g.image.height - y;
 | 
						|
  endif
 | 
						|
 | 
						|
  if (event == highgui.CV_EVENT_LBUTTONDOWN)
 | 
						|
    ## user has click, so memorize it
 | 
						|
    pt = cv.cvPoint (x, y);
 | 
						|
    g.add_remove_pt = true;
 | 
						|
  endif
 | 
						|
endfunction
 | 
						|
 | 
						|
#############################################################################
 | 
						|
## so, here is the main part of the program
 | 
						|
 | 
						|
 | 
						|
filename = "/home/x/work/sneaker/dvgrab-001.avi";
 | 
						|
if (size(argv, 1)>1)
 | 
						|
  filename=argv(){1};
 | 
						|
endif
 | 
						|
 | 
						|
capture = highgui.cvCreateFileCapture (filename);
 | 
						|
 | 
						|
## check that capture device is OK
 | 
						|
if (!swig_this(capture))
 | 
						|
  printf("Error opening capture device\n");
 | 
						|
  exit(1)
 | 
						|
endif
 | 
						|
 | 
						|
## display a small howto use it
 | 
						|
printf("Hot keys: \n");
 | 
						|
printf("\tESC - quit the program\n");
 | 
						|
printf("\tr - auto-initialize tracking\n");
 | 
						|
printf("\tc - delete all the points\n");
 | 
						|
printf("\tn - switch the \"night\" mode on/off\n");
 | 
						|
printf("To add/remove a feature point click it\n");
 | 
						|
 | 
						|
## first, create the necessary windows
 | 
						|
highgui.cvNamedWindow ('LkDemo', 1);
 | 
						|
 | 
						|
## register the mouse callback
 | 
						|
highgui.cvSetMouseCallback ('LkDemo', @on_mouse, []);
 | 
						|
 | 
						|
while (1)
 | 
						|
  ## do forever
 | 
						|
 | 
						|
  ## 1. capture the current image
 | 
						|
  frame = highgui.cvQueryFrame (capture);
 | 
						|
  if (swig_this(frame) == 0)
 | 
						|
    ## no image captured... end the processing
 | 
						|
    break
 | 
						|
  endif
 | 
						|
 | 
						|
  if (swig_this(g.image) == 0),
 | 
						|
    ## create the images we need
 | 
						|
    g.image = cv.cvCreateImage (cv.cvGetSize (frame), 8, 3);
 | 
						|
#    g.image.origin = frame.origin;
 | 
						|
    g.grey = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1);
 | 
						|
    g.prev_grey = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1);
 | 
						|
    g.pyramid = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1);
 | 
						|
    g.prev_pyramid = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1);
 | 
						|
    g.points = {[], []};
 | 
						|
  endif
 | 
						|
 | 
						|
  ## copy the frame, so we can draw on it
 | 
						|
  cv.cvCopy (frame, g.image)
 | 
						|
 | 
						|
  ## create a grey version of the image
 | 
						|
  cv.cvCvtColor (g.image, g.grey, cv.CV_BGR2GRAY)
 | 
						|
 | 
						|
  if (g.night_mode)
 | 
						|
    ## night mode: only display the points
 | 
						|
    cv.cvSetZero (g.image);
 | 
						|
  endif
 | 
						|
 | 
						|
  if (g.need_to_init)
 | 
						|
    ## we want to search all the good points
 | 
						|
 | 
						|
    ## create the wanted images
 | 
						|
    eig = cv.cvCreateImage (cv.cvGetSize (g.grey), 32, 1);
 | 
						|
    temp = cv.cvCreateImage (cv.cvGetSize (g.grey), 32, 1);
 | 
						|
 | 
						|
    ## the default parameters
 | 
						|
    quality = 0.01;
 | 
						|
    min_distance = 10;
 | 
						|
 | 
						|
    ## search the good points
 | 
						|
    g.points {1} = cv.cvGoodFeaturesToTrack (g.grey, eig, temp,MAX_COUNT,quality, min_distance, [], 3, 0, 0.04);
 | 
						|
 | 
						|
    ## refine the corner locations
 | 
						|
    cv.cvFindCornerSubPix (g.grey,g.points {1},cv.cvSize (win_size, win_size), cv.cvSize (-1, -1),cv.cvTermCriteria (cv.CV_TERMCRIT_ITER | cv.CV_TERMCRIT_EPS,20, 0.03));
 | 
						|
    
 | 
						|
  elseif (size (g.points {1}, 2) > 0)
 | 
						|
    ## we have points, so display them
 | 
						|
 | 
						|
    ## calculate the optical flow
 | 
						|
    [tmp, status] = cv.cvCalcOpticalFlowPyrLK (g.prev_grey, g.grey, g.prev_pyramid, g.pyramid,g.points {1}, size (g.points {1},2),cv.cvSize (win_size, win_size), 3,size (g.points {1}, 2),[],cv.cvTermCriteria (bitor(cv.CV_TERMCRIT_ITER,cv.CV_TERMCRIT_EPS),20, 0.03),g.flags);
 | 
						|
    g.points {2} = tmp;
 | 
						|
 | 
						|
    ## initializations
 | 
						|
    point_counter = -1;
 | 
						|
    new_points = {};
 | 
						|
 | 
						|
    for the_point = g.points {2},
 | 
						|
      the_point = the_point{1};
 | 
						|
      ## go trough all the points
 | 
						|
 | 
						|
      ## increment the counter
 | 
						|
      point_counter += 1;
 | 
						|
 | 
						|
      if (g.add_remove_pt)
 | 
						|
	## we have a point to add, so see if it is close to
 | 
						|
	## another one. If yes, don't use it
 | 
						|
        dx = pt.x - the_point.x;
 | 
						|
        dy = pt.y - the_point.y;
 | 
						|
        if (dx * dx + dy * dy <= 25)
 | 
						|
	  ## too close
 | 
						|
          g.add_remove_pt = 0;
 | 
						|
          continue;
 | 
						|
	endif
 | 
						|
      endif
 | 
						|
 | 
						|
      if (!status {point_counter+1})
 | 
						|
	## we will disable this point
 | 
						|
        continue;
 | 
						|
      endif
 | 
						|
 | 
						|
      ## this point is a correct point
 | 
						|
      new_points{end+1} = the_point;
 | 
						|
 | 
						|
      ## draw the current point
 | 
						|
      cv.cvCircle (g.image, {the_point.x, the_point.y},3, cv.cvScalar (0, 255, 0, 0),-1, 8, 0);
 | 
						|
    endfor
 | 
						|
 | 
						|
    ## set back the points we keep;
 | 
						|
    points {1} = new_points;
 | 
						|
  endif
 | 
						|
 | 
						|
  if (g.add_remove_pt)
 | 
						|
    ## we want to add a point
 | 
						|
    points {1} = append (points {1}, cv.cvPointTo32f (pt));
 | 
						|
 | 
						|
    ## refine the corner locations
 | 
						|
    g.points {1} = cv.cvFindCornerSubPix  \
 | 
						|
    (g.grey, {points {1}}, cv.cvSize (win_size, win_size), cv.cvSize \
 | 
						|
     (-1, -1), cv.cvTermCriteria (bitor(cv.CV_TERMCRIT_ITER, cv.CV_TERMCRIT_EPS),20, 0.03));
 | 
						|
 | 
						|
    ## we are no more in "add_remove_pt" mode
 | 
						|
    g.add_remove_pt = false
 | 
						|
  endif
 | 
						|
 | 
						|
  ## swapping
 | 
						|
  tmp = g.prev_grey; g.prev_grey = g.grey; g.grey = tmp;
 | 
						|
  tmp = g.prev_pyramid; g.prev_pyramid = g.pyramid; g.pyramid = tmp;
 | 
						|
  tmp = g.points{1}; g.points{1} = g.points{2}; g.points{2} = tmp;
 | 
						|
  g.need_to_init = false;
 | 
						|
  
 | 
						|
  ## we can now display the image
 | 
						|
  highgui.cvShowImage ('LkDemo', g.image)
 | 
						|
 | 
						|
  ## handle events
 | 
						|
  c = highgui.cvWaitKey (10);
 | 
						|
 | 
						|
  if (c == 27)
 | 
						|
    ## user has press the ESC key, so exit
 | 
						|
    break
 | 
						|
  endif
 | 
						|
 | 
						|
  ## processing depending on the character
 | 
						|
  if (c == int32('r'))
 | 
						|
    g.need_to_init = true;
 | 
						|
  elseif (c == int32('c'))
 | 
						|
    g.points = {[], []};
 | 
						|
  elseif (c == int32('n'))
 | 
						|
    g.night_mode = !g.night_mode;
 | 
						|
  endif
 | 
						|
endwhile
 |