]> rtime.felk.cvut.cz Git - opencv.git/blob - opencv/samples/c/find_obj_calonder.cpp
Calonder sample parameters were modified
[opencv.git] / opencv / samples / c / find_obj_calonder.cpp
1 //Calonder descriptor sample
2
3 #include <cxcore.h>
4 #include <cv.h>
5 #include <cvaux.h>
6 #include <highgui.h>
7 #include <vector>
8 using namespace std;
9
10 // Number of training points (set to -1 to use all points)
11 const int n_points = -1;
12
13 //Draw the border of projection of train image calculed by averaging detected correspondences
14 const bool draw_border = true;
15
16 void cvmSet6(CvMat* m, int row, int col, float val1, float val2, float val3, float val4, float val5, float val6)
17 {
18     cvmSet(m, row, col, val1);
19     cvmSet(m, row, col + 1, val2);
20     cvmSet(m, row, col + 2, val3);
21     cvmSet(m, row, col + 3, val4);
22     cvmSet(m, row, col + 4, val5);
23     cvmSet(m, row, col + 5, val6);
24 }
25
26 void FindAffineTransform(const vector<CvPoint>& p1, const vector<CvPoint>& p2, CvMat* affine)
27 {
28     int eq_num = 2*(int)p1.size();
29     CvMat* A = cvCreateMat(eq_num, 6, CV_32FC1);
30     CvMat* B = cvCreateMat(eq_num, 1, CV_32FC1);
31     CvMat* X = cvCreateMat(6, 1, CV_32FC1);
32     
33     for(int i = 0; i < (int)p1.size(); i++)
34     {
35         cvmSet6(A, 2*i, 0, p1[i].x, p1[i].y, 1, 0, 0, 0);
36         cvmSet6(A, 2*i + 1, 0, 0, 0, 0, p1[i].x, p1[i].y, 1);
37         cvmSet(B, 2*i, 0, p2[i].x);
38         cvmSet(B, 2*i + 1, 0, p2[i].y);
39     }
40     
41     cvSolve(A, B, X, CV_SVD);
42     
43     cvmSet(affine, 0, 0, cvmGet(X, 0, 0));
44     cvmSet(affine, 0, 1, cvmGet(X, 1, 0));
45     cvmSet(affine, 0, 2, cvmGet(X, 2, 0));
46     cvmSet(affine, 1, 0, cvmGet(X, 3, 0));
47     cvmSet(affine, 1, 1, cvmGet(X, 4, 0));
48     cvmSet(affine, 1, 2, cvmGet(X, 5, 0));
49     
50     cvReleaseMat(&A);
51     cvReleaseMat(&B);
52     cvReleaseMat(&X);
53 }
54
55 void MapVectorAffine(const vector<CvPoint>& p1, vector<CvPoint>& p2, CvMat* transform)
56 {
57     float a = cvmGet(transform, 0, 0);
58     float b = cvmGet(transform, 0, 1);
59     float c = cvmGet(transform, 0, 2);
60     float d = cvmGet(transform, 1, 0);
61     float e = cvmGet(transform, 1, 1);
62     float f = cvmGet(transform, 1, 2);
63     
64     for(int i = 0; i < (int)p1.size(); i++)
65     {
66         float x = a*p1[i].x + b*p1[i].y + c;
67         float y = d*p1[i].x + e*p1[i].y + f;
68         p2.push_back(cvPoint(x, y));
69     }
70 }
71
72
73 float CalcAffineReprojectionError(const vector<CvPoint>& p1, const vector<CvPoint>& p2, CvMat* transform)
74 {
75     vector<CvPoint> mapped_p1;
76     MapVectorAffine(p1, mapped_p1, transform);
77     float error = 0;
78     for(int i = 0; i < (int)p2.size(); i++)
79     {
80         error += ((p2[i].x - mapped_p1[i].x)*(p2[i].x - mapped_p1[i].x)+(p2[i].y - mapped_p1[i].y)*(p2[i].y - mapped_p1[i].y));
81     }
82     
83     error /= p2.size();
84     
85     return error;
86 }
87
88
89 int main( int argc, char** argv )
90 {
91
92         IplImage* test_image;
93         IplImage* train_image;
94         if (argc < 3)
95         {
96                 
97                 test_image = cvLoadImage("box_in_scene.png",0);
98                 train_image = cvLoadImage("box.png ",0);
99                 if (!test_image || !train_image)
100                 {
101                         printf("Usage: calonder_sample <train_image> <test_image>");
102                         return 0;
103                 }
104         }
105         else
106         {
107                 test_image = cvLoadImage(argv[2],0);
108                 train_image = cvLoadImage(argv[1],0);
109         }
110
111
112
113
114
115         if (!train_image)
116         {
117                 printf("Unable to load train image\n");
118                 return 0;
119         }
120
121         if (!test_image)
122         {
123                 printf("Unable to load test image\n");
124                 return 0;
125         }
126
127
128
129         CvMemStorage* storage = cvCreateMemStorage(0);
130     CvSeq *objectKeypoints = 0, *objectDescriptors = 0;
131     CvSeq *imageKeypoints = 0, *imageDescriptors = 0;
132     CvSURFParams params = cvSURFParams(500, 1);
133         cvExtractSURF( test_image, 0, &imageKeypoints, &imageDescriptors, storage, params );
134         cvExtractSURF( train_image, 0, &objectKeypoints, &objectDescriptors, storage, params );
135
136
137         cv::RTreeClassifier detector;
138         int patch_width = cv::PATCH_SIZE;
139         int patch_height = cv::PATCH_SIZE;
140         vector<cv::BaseKeypoint> base_set;
141         int i=0;
142         CvSURFPoint* point;
143
144
145         for (i=0;i<(n_points > 0 ? n_points : objectKeypoints->total);i++)
146         {
147                 point=(CvSURFPoint*)cvGetSeqElem(objectKeypoints,i);
148                 base_set.push_back(cv::BaseKeypoint(point->pt.x,point->pt.y,train_image));
149         }
150
151         //Detector training
152     cv::RNG rng( cvGetTickCount() );
153         cv::PatchGenerator gen(0,255,2,false,0.7,1.3,-CV_PI/3,CV_PI/3,-CV_PI/3,CV_PI/3);
154
155         printf("RTree Classifier training...\n");
156         detector.train(base_set,rng,gen,24,cv::DEFAULT_DEPTH,2000,(int)base_set.size(),detector.DEFAULT_NUM_QUANT_BITS);
157         printf("Done\n");
158
159         float* signature = new float[detector.original_num_classes()];
160         float* best_corr;
161         int* best_corr_idx;
162         if (imageKeypoints->total > 0)
163         {
164                 best_corr = new float[imageKeypoints->total];
165                 best_corr_idx = new int[imageKeypoints->total];
166         }
167
168         for(i=0; i < imageKeypoints->total; i++)
169         {
170                 point=(CvSURFPoint*)cvGetSeqElem(imageKeypoints,i);
171                 int part_idx = -1;
172                 float prob = 0.0f;
173
174
175                 CvRect roi = cvRect((int)(point->pt.x) - patch_width/2,(int)(point->pt.y) - patch_height/2, patch_width, patch_height);
176                 cvSetImageROI(test_image, roi);
177                 roi = cvGetImageROI(test_image);
178                 if(roi.width != patch_width || roi.height != patch_height)
179                 {
180                         best_corr_idx[i] = part_idx;
181                         best_corr[i] = prob;
182                 }
183                 else
184                 {
185                         cvSetImageROI(test_image, roi);
186                         IplImage* roi_image = cvCreateImage(cvSize(roi.width, roi.height), test_image->depth, test_image->nChannels);
187                         cvCopy(test_image,roi_image);
188
189                         detector.getSignature(roi_image, signature);
190
191
192                         for (int j = 0; j< detector.original_num_classes();j++)
193                         {
194                                 if (prob < signature[j])
195                                 {
196                                         part_idx = j;
197                                         prob = signature[j];
198                                 }
199                         }
200
201                         best_corr_idx[i] = part_idx;
202                         best_corr[i] = prob;
203
204                         
205                         if (roi_image)
206                                 cvReleaseImage(&roi_image);
207                 }
208                 cvResetImageROI(test_image);
209         }
210
211         float min_prob = 0.0f;
212         vector<CvPoint> object;
213         vector<CvPoint> features;
214
215         for (int j=0;j<objectKeypoints->total;j++)
216         {
217                 float prob = 0.0f;
218                 int idx = -1;
219                 for (i = 0; i<imageKeypoints->total;i++)
220                 {
221                         if ((best_corr_idx[i]!=j)||(best_corr[i] < min_prob))
222                                 continue;
223
224                         if (best_corr[i] > prob)
225                         {
226                                 prob = best_corr[i];
227                                 idx = i;
228                         }
229                 }
230                 if (idx >=0)
231                 {
232                         point=(CvSURFPoint*)cvGetSeqElem(objectKeypoints,j);
233                         object.push_back(cvPoint((int)point->pt.x,(int)point->pt.y));
234                         point=(CvSURFPoint*)cvGetSeqElem(imageKeypoints,idx);
235                         features.push_back(cvPoint((int)point->pt.x,(int)point->pt.y));
236                 }
237         }
238         if ((int)object.size() > 3)
239         {
240                 CvMat* affine = cvCreateMat(2, 3, CV_32FC1);
241                 FindAffineTransform(object,features,affine);
242
243                 vector<CvPoint> corners;
244                 vector<CvPoint> mapped_corners;
245                 corners.push_back(cvPoint(0,0));
246                 corners.push_back(cvPoint(0,train_image->height));
247                 corners.push_back(cvPoint(train_image->width,0));
248                 corners.push_back(cvPoint(train_image->width,train_image->height));
249                 MapVectorAffine(corners,mapped_corners,affine);
250
251                 //Drawing the result
252                 IplImage* result = cvCreateImage(cvSize(test_image->width > train_image->width ? test_image->width : train_image->width,
253                         train_image->height + test_image->height),
254                         test_image->depth, test_image->nChannels);
255                 cvSetImageROI(result,cvRect(0,0,train_image->width, train_image->height));
256                 cvCopy(train_image,result);
257                 cvResetImageROI(result);
258                 cvSetImageROI(result,cvRect(0,train_image->height,test_image->width, test_image->height));
259                 cvCopy(test_image,result);
260                 cvResetImageROI(result);
261
262                 for (int i=0;i<(int)features.size();i++)
263                 {
264                         cvLine(result,object[i],cvPoint(features[i].x,features[i].y+train_image->height),cvScalar(255));
265                 }
266
267                 if (draw_border)
268                 {
269                         cvLine(result,cvPoint(mapped_corners[0].x, mapped_corners[0].y+train_image->height),
270                                 cvPoint(mapped_corners[1].x, mapped_corners[1].y+train_image->height),cvScalar(150),3);
271                         cvLine(result,cvPoint(mapped_corners[0].x, mapped_corners[0].y+train_image->height),
272                                 cvPoint(mapped_corners[2].x, mapped_corners[2].y+train_image->height),cvScalar(150),3);
273                         cvLine(result,cvPoint(mapped_corners[1].x, mapped_corners[1].y+train_image->height),
274                                 cvPoint(mapped_corners[3].x, mapped_corners[3].y+train_image->height),cvScalar(150),3);
275                         cvLine(result,cvPoint(mapped_corners[2].x, mapped_corners[2].y+train_image->height),
276                                 cvPoint(mapped_corners[3].x, mapped_corners[3].y+train_image->height),cvScalar(150),3);
277                 }
278
279                 cvSaveImage("Result.jpg",result);
280                 cvNamedWindow("Result",0);
281                 cvShowImage("Result",result);
282                 cvWaitKey();
283                 cvReleaseMat(&affine);
284                 cvReleaseImage(&result);
285         }
286         else
287         {
288                 printf("Unable to find correspondence\n");
289         }
290
291
292         
293         
294         if (signature)
295                 delete[] signature;
296         if (best_corr)
297                 delete[] best_corr;
298         cvReleaseMemStorage(&storage);
299         cvReleaseImage(&train_image);
300         cvReleaseImage(&test_image);
301
302         return 0;
303 }