changeset 18:ef35d5f111e4

incorporated code to use KLT
author Nicolas Saunier <nico@confins.net>
date Fri, 27 Nov 2009 00:21:18 -0500
parents 9403759cf2c1
children 5a21d2cfee44
files c/Makefile c/track-features.cpp
diffstat 2 files changed, 186 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/c/Makefile	Thu Nov 26 23:44:57 2009 -0500
+++ b/c/Makefile	Fri Nov 27 00:21:18 2009 -0500
@@ -48,11 +48,17 @@
 
 default: builddir all
 
-all: test-pixels optical-flow
+all: test-pixels optical-flow track-features
 
 builddir:
 	@createdirectory.sh $(BUILD_DIR)
 
+track-features.o: track-features.cpp
+	$(CXX) -I../../klt $(INCLUDE) $^ -c
+
+track-features: track-features.o $(OBJS)
+	$(CXX) $(CFLAGS) $(LIBS) -L../../klt $^ -o $(BUILD_DIR)/$@ $(LDFLAGS) -lklt
+
 optical-flow: optical-flow.o $(OBJS)
 	$(CXX) $(CFLAGS) $(LIBS) $^ -o $(BUILD_DIR)/$@ $(LDFLAGS)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/c/track-features.cpp	Fri Nov 27 00:21:18 2009 -0500
@@ -0,0 +1,179 @@
+#include "cvutils.hpp"
+#include "utils.hpp"
+
+#include "klt.h"
+
+#include "opencv/cv.h"
+#include "opencv/highgui.h"
+
+#include <iostream>
+#include <string>
+
+using namespace std;
+
+#define FEAT_VAL(x) ((x) > 0) ? 1 : x // 1 means the features was replaced
+
+void cvGetCharArray(IplImage *image, unsigned char* img, int width, int height);
+
+int main(int argc, char *argv[]) {
+  //cout << "Hello World" << endl;
+
+  KLT_TrackingContext tc;
+  KLT_FeatureList fl;
+  KLT_FeatureTable ft;
+  KLT_Feature feature;
+
+  int i,j;
+  string fnamein, fnameout, tmp;
+  string sequenceDir="../test-images";
+  FILE* out;
+
+  IplImage *image;
+  int width, height;
+  unsigned char *img1, *img2;
+
+//   CvCapture *inputVideo = 0;
+//   if (argc == 1)
+//     inputVideo = cvCreateCameraCapture(-1);
+//   else
+//     inputVideo = cvCaptureFromFile(argv[1]);
+
+  int frameNum = 0;
+
+  if (argc < 7){
+    printf("\ntrack sequenceFile startFrame numFrames numFeatures min_dist window_size\n");
+    return (-1);
+  }
+
+  // parameters for tracking
+  char* sequenceFile = argv[1];
+  int startFrame = (int) strtol(argv[2],NULL,10);
+  int nFrames = (int) strtol(argv[3],NULL,10);
+  int nFeatures = (int) strtol(argv[4],NULL,10);
+  int mindist = (int) strtol(argv[5],NULL,10);
+  int window_size = (int) strtol(argv[6],NULL,10);
+
+  fnamein = sequenceFile;//sequenceDir+"/"++".avi"
+  CvCapture* sequence = cvCaptureFromFile(fnamein.c_str());
+  if (sequence == NULL) {
+    cout << "Pb reading " << fnamein << " file.";
+    exit(0);
+  }
+    
+
+  // from http://ai.stanford.edu/~dstavens/cs223b/optical_flow_demo.cpp
+  /* This is a hack. If we don't call this first then getting capture
+   * properties (below) won't work right. This is an OpenCV bug. We
+   * ignore the return value here. But it's actually a video frame.
+   */
+
+  cvQueryFrame(sequence);
+  /* Read the video's frame size out of the AVI. */
+  CvSize frame_size;
+  frame_size.height = cvGetCaptureProperty(sequence, CV_CAP_PROP_FRAME_HEIGHT );
+  frame_size.width = cvGetCaptureProperty(sequence, CV_CAP_PROP_FRAME_WIDTH );
+  /* Determine the number of frames in the AVI. */
+  int number_of_frames;
+  /* Go to the end of the AVI (ie: the fraction is "1") */
+  cvSetCaptureProperty(sequence, CV_CAP_PROP_POS_AVI_RATIO, 1.);
+  /* Now that we're at the end, read the AVI position in frames */
+  number_of_frames = cvGetCaptureProperty( sequence, CV_CAP_PROP_POS_FRAMES );
+  /* Return to the beginning */
+  cvSetCaptureProperty(sequence, CV_CAP_PROP_POS_FRAMES, 0. );
+  printf("%d %d %d\n", frame_size.height, frame_size.width, number_of_frames);
+
+  if (nFrames < 0)
+    nFrames = number_of_frames;
+
+  // go forward to the startFrame
+  //cvNamedWindow("Image",1);
+
+  for (i=1; i<startFrame; i++) { // pb if more than the number of frames
+      image = cvQueryFrame(sequence);
+      //if (i%1000==0) {
+      //printf("%d\n", i);
+      //cvShowImage("Image",image);
+      //WaitKey(0);
+      //}
+    }
+
+  img1 = (unsigned char*)malloc(frame_size.height*frame_size.width*sizeof(unsigned char));
+  img2 = (unsigned char*)malloc(frame_size.height*frame_size.width*sizeof(unsigned char));
+
+  // KLT initialization
+  tc = KLTCreateTrackingContext();
+  fl = KLTCreateFeatureList(nFeatures);
+  ft = KLTCreateFeatureTable(nFrames, nFeatures);
+  tc->sequentialMode = TRUE;
+  tc->mindist = mindist;
+  tc->window_width = window_size;
+  tc->window_height = window_size;
+  KLTSetVerbosity(0);
+  tc->affineConsistencyCheck = 2;
+
+  // initialization of the first frame
+  image = cvQueryFrame(sequence);
+  cvGetCharArray(image, img1, frame_size.width, frame_size.height);
+
+  KLTSelectGoodFeatures(tc, img1, frame_size.width, frame_size.height, fl);
+  KLTStoreFeatureList(fl, ft, 0);
+  //KLTWriteFeatureListToPPM(fl, img1, frame_size.width, frame_size.height, "feat0000.ppm");
+
+  i=1;
+  while (((image = cvQueryFrame(sequence)) != NULL) && (i<nFrames)) {
+    cvGetCharArray(image, img2, frame_size.width, frame_size.height);
+
+    // feature tracking
+    KLTTrackFeatures(tc, img1, img2, frame_size.width, frame_size.height, fl);
+    KLTReplaceLostFeatures(tc, img2, frame_size.width, frame_size.height, fl);
+    KLTStoreFeatureList(fl, ft, i);
+
+    img1 = img2;
+    // unquote if you want to write the frames with the tracked features.
+    //sprintf(fnameout, "feat%04d.ppm", startFrame+i);
+    //KLTWriteFeatureListToPPM(fl, img2, frame_size.width, frame_size.height, fnameout);
+    //printf("%04d\n", i);
+    i++;
+  }
+
+  printf("%d\n", i);
+
+  // writing feature file
+  fnameout = "features.txt";//"features-"%s"-"%d"-"%d"-"%d".txt", sequenceFile, nFeatures, tc->mindist, tc->window_width);
+  //KLTWriteFeatureTable(ft, fnameout, "%5.1f");
+
+  out = fopen(fnameout.c_str(),"w");
+  if(out!=NULL){
+    fprintf(out,"%%StartFrame: 0\n");
+    fprintf(out,"%%NumFrames: %d\n",nFrames);
+    
+    // 1 feature / line
+    // x1 y1 val1 x2 y2 val2 ... (1 2... frame numbers)
+    for (j = 0 ; j < ft->nFeatures ; j++)  {
+      fprintf(out, "\n");
+      for (i = 0 ; i < ft->nFrames ; i++){
+        feature = ft->feature[j][i];
+	fprintf(out,"%.2f %.2f %d ",(float)feature->x,(float)feature->y,FEAT_VAL(feature->val));
+      }
+    }      
+    
+    fclose(out);
+  }        
+  else
+    printf("\nError opening feature file\n");
+
+  cvReleaseCapture(&sequence);
+
+  return 1;
+}
+
+// converts a frame from IplImage format (OpenCV) to an array of unsigned char for KLT
+void cvGetCharArray(IplImage *image, unsigned char* img, int width, int height) {
+  int x, y;
+  
+  for(y=0 ; y < height ; y++) {
+    for(x=0; x < width ; x++) {
+      img[(height-y-1)*width+x] = (image->imageData+image->widthStep*y)[x*3];
+    }
+  }
+}