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 }