Mercurial > hg > nsaunier > traffic-intelligence
comparison c/track-features.cpp @ 18:ef35d5f111e4
incorporated code to use KLT
| author | Nicolas Saunier <nico@confins.net> |
|---|---|
| date | Fri, 27 Nov 2009 00:21:18 -0500 |
| parents | |
| children | ef0d7caf8e91 |
comparison
equal
deleted
inserted
replaced
| 17:9403759cf2c1 | 18:ef35d5f111e4 |
|---|---|
| 1 #include "cvutils.hpp" | |
| 2 #include "utils.hpp" | |
| 3 | |
| 4 #include "klt.h" | |
| 5 | |
| 6 #include "opencv/cv.h" | |
| 7 #include "opencv/highgui.h" | |
| 8 | |
| 9 #include <iostream> | |
| 10 #include <string> | |
| 11 | |
| 12 using namespace std; | |
| 13 | |
| 14 #define FEAT_VAL(x) ((x) > 0) ? 1 : x // 1 means the features was replaced | |
| 15 | |
| 16 void cvGetCharArray(IplImage *image, unsigned char* img, int width, int height); | |
| 17 | |
| 18 int main(int argc, char *argv[]) { | |
| 19 //cout << "Hello World" << endl; | |
| 20 | |
| 21 KLT_TrackingContext tc; | |
| 22 KLT_FeatureList fl; | |
| 23 KLT_FeatureTable ft; | |
| 24 KLT_Feature feature; | |
| 25 | |
| 26 int i,j; | |
| 27 string fnamein, fnameout, tmp; | |
| 28 string sequenceDir="../test-images"; | |
| 29 FILE* out; | |
| 30 | |
| 31 IplImage *image; | |
| 32 int width, height; | |
| 33 unsigned char *img1, *img2; | |
| 34 | |
| 35 // CvCapture *inputVideo = 0; | |
| 36 // if (argc == 1) | |
| 37 // inputVideo = cvCreateCameraCapture(-1); | |
| 38 // else | |
| 39 // inputVideo = cvCaptureFromFile(argv[1]); | |
| 40 | |
| 41 int frameNum = 0; | |
| 42 | |
| 43 if (argc < 7){ | |
| 44 printf("\ntrack sequenceFile startFrame numFrames numFeatures min_dist window_size\n"); | |
| 45 return (-1); | |
| 46 } | |
| 47 | |
| 48 // parameters for tracking | |
| 49 char* sequenceFile = argv[1]; | |
| 50 int startFrame = (int) strtol(argv[2],NULL,10); | |
| 51 int nFrames = (int) strtol(argv[3],NULL,10); | |
| 52 int nFeatures = (int) strtol(argv[4],NULL,10); | |
| 53 int mindist = (int) strtol(argv[5],NULL,10); | |
| 54 int window_size = (int) strtol(argv[6],NULL,10); | |
| 55 | |
| 56 fnamein = sequenceFile;//sequenceDir+"/"++".avi" | |
| 57 CvCapture* sequence = cvCaptureFromFile(fnamein.c_str()); | |
| 58 if (sequence == NULL) { | |
| 59 cout << "Pb reading " << fnamein << " file."; | |
| 60 exit(0); | |
| 61 } | |
| 62 | |
| 63 | |
| 64 // from http://ai.stanford.edu/~dstavens/cs223b/optical_flow_demo.cpp | |
| 65 /* This is a hack. If we don't call this first then getting capture | |
| 66 * properties (below) won't work right. This is an OpenCV bug. We | |
| 67 * ignore the return value here. But it's actually a video frame. | |
| 68 */ | |
| 69 | |
| 70 cvQueryFrame(sequence); | |
| 71 /* Read the video's frame size out of the AVI. */ | |
| 72 CvSize frame_size; | |
| 73 frame_size.height = cvGetCaptureProperty(sequence, CV_CAP_PROP_FRAME_HEIGHT ); | |
| 74 frame_size.width = cvGetCaptureProperty(sequence, CV_CAP_PROP_FRAME_WIDTH ); | |
| 75 /* Determine the number of frames in the AVI. */ | |
| 76 int number_of_frames; | |
| 77 /* Go to the end of the AVI (ie: the fraction is "1") */ | |
| 78 cvSetCaptureProperty(sequence, CV_CAP_PROP_POS_AVI_RATIO, 1.); | |
| 79 /* Now that we're at the end, read the AVI position in frames */ | |
| 80 number_of_frames = cvGetCaptureProperty( sequence, CV_CAP_PROP_POS_FRAMES ); | |
| 81 /* Return to the beginning */ | |
| 82 cvSetCaptureProperty(sequence, CV_CAP_PROP_POS_FRAMES, 0. ); | |
| 83 printf("%d %d %d\n", frame_size.height, frame_size.width, number_of_frames); | |
| 84 | |
| 85 if (nFrames < 0) | |
| 86 nFrames = number_of_frames; | |
| 87 | |
| 88 // go forward to the startFrame | |
| 89 //cvNamedWindow("Image",1); | |
| 90 | |
| 91 for (i=1; i<startFrame; i++) { // pb if more than the number of frames | |
| 92 image = cvQueryFrame(sequence); | |
| 93 //if (i%1000==0) { | |
| 94 //printf("%d\n", i); | |
| 95 //cvShowImage("Image",image); | |
| 96 //WaitKey(0); | |
| 97 //} | |
| 98 } | |
| 99 | |
| 100 img1 = (unsigned char*)malloc(frame_size.height*frame_size.width*sizeof(unsigned char)); | |
| 101 img2 = (unsigned char*)malloc(frame_size.height*frame_size.width*sizeof(unsigned char)); | |
| 102 | |
| 103 // KLT initialization | |
| 104 tc = KLTCreateTrackingContext(); | |
| 105 fl = KLTCreateFeatureList(nFeatures); | |
| 106 ft = KLTCreateFeatureTable(nFrames, nFeatures); | |
| 107 tc->sequentialMode = TRUE; | |
| 108 tc->mindist = mindist; | |
| 109 tc->window_width = window_size; | |
| 110 tc->window_height = window_size; | |
| 111 KLTSetVerbosity(0); | |
| 112 tc->affineConsistencyCheck = 2; | |
| 113 | |
| 114 // initialization of the first frame | |
| 115 image = cvQueryFrame(sequence); | |
| 116 cvGetCharArray(image, img1, frame_size.width, frame_size.height); | |
| 117 | |
| 118 KLTSelectGoodFeatures(tc, img1, frame_size.width, frame_size.height, fl); | |
| 119 KLTStoreFeatureList(fl, ft, 0); | |
| 120 //KLTWriteFeatureListToPPM(fl, img1, frame_size.width, frame_size.height, "feat0000.ppm"); | |
| 121 | |
| 122 i=1; | |
| 123 while (((image = cvQueryFrame(sequence)) != NULL) && (i<nFrames)) { | |
| 124 cvGetCharArray(image, img2, frame_size.width, frame_size.height); | |
| 125 | |
| 126 // feature tracking | |
| 127 KLTTrackFeatures(tc, img1, img2, frame_size.width, frame_size.height, fl); | |
| 128 KLTReplaceLostFeatures(tc, img2, frame_size.width, frame_size.height, fl); | |
| 129 KLTStoreFeatureList(fl, ft, i); | |
| 130 | |
| 131 img1 = img2; | |
| 132 // unquote if you want to write the frames with the tracked features. | |
| 133 //sprintf(fnameout, "feat%04d.ppm", startFrame+i); | |
| 134 //KLTWriteFeatureListToPPM(fl, img2, frame_size.width, frame_size.height, fnameout); | |
| 135 //printf("%04d\n", i); | |
| 136 i++; | |
| 137 } | |
| 138 | |
| 139 printf("%d\n", i); | |
| 140 | |
| 141 // writing feature file | |
| 142 fnameout = "features.txt";//"features-"%s"-"%d"-"%d"-"%d".txt", sequenceFile, nFeatures, tc->mindist, tc->window_width); | |
| 143 //KLTWriteFeatureTable(ft, fnameout, "%5.1f"); | |
| 144 | |
| 145 out = fopen(fnameout.c_str(),"w"); | |
| 146 if(out!=NULL){ | |
| 147 fprintf(out,"%%StartFrame: 0\n"); | |
| 148 fprintf(out,"%%NumFrames: %d\n",nFrames); | |
| 149 | |
| 150 // 1 feature / line | |
| 151 // x1 y1 val1 x2 y2 val2 ... (1 2... frame numbers) | |
| 152 for (j = 0 ; j < ft->nFeatures ; j++) { | |
| 153 fprintf(out, "\n"); | |
| 154 for (i = 0 ; i < ft->nFrames ; i++){ | |
| 155 feature = ft->feature[j][i]; | |
| 156 fprintf(out,"%.2f %.2f %d ",(float)feature->x,(float)feature->y,FEAT_VAL(feature->val)); | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 fclose(out); | |
| 161 } | |
| 162 else | |
| 163 printf("\nError opening feature file\n"); | |
| 164 | |
| 165 cvReleaseCapture(&sequence); | |
| 166 | |
| 167 return 1; | |
| 168 } | |
| 169 | |
| 170 // converts a frame from IplImage format (OpenCV) to an array of unsigned char for KLT | |
| 171 void cvGetCharArray(IplImage *image, unsigned char* img, int width, int height) { | |
| 172 int x, y; | |
| 173 | |
| 174 for(y=0 ; y < height ; y++) { | |
| 175 for(x=0; x < width ; x++) { | |
| 176 img[(height-y-1)*width+x] = (image->imageData+image->widthStep*y)[x*3]; | |
| 177 } | |
| 178 } | |
| 179 } |
