opencv-ffi 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +15 -0
  3. data/README.md +126 -0
  4. data/Rakefile +52 -0
  5. data/docs/DocsIndex.md +1 -0
  6. data/docs/examples/load_image.rb +25 -0
  7. data/ext/Rakefile +13 -0
  8. data/ext/aishack-sift/.gitignore +4 -0
  9. data/ext/aishack-sift/Descriptor.h +34 -0
  10. data/ext/aishack-sift/KeyPoint.h +38 -0
  11. data/ext/aishack-sift/README +20 -0
  12. data/ext/aishack-sift/SIFT.cpp +1036 -0
  13. data/ext/aishack-sift/SIFT.h +84 -0
  14. data/ext/aishack-sift/example/.gitignore +2 -0
  15. data/ext/aishack-sift/example/Makefile +24 -0
  16. data/ext/aishack-sift/example/MySIFT.cpp +29 -0
  17. data/ext/aishack-sift/mkrf_conf.rb +13 -0
  18. data/ext/aishack-sift/siftlib.cpp +85 -0
  19. data/ext/eigen/.gitignore +4 -0
  20. data/ext/eigen/eigen_polynomial.cpp +41 -0
  21. data/ext/eigen/eigen_svd.cpp +100 -0
  22. data/ext/eigen/mkrf_conf.rb +14 -0
  23. data/ext/mkrf-monkey.rb +85 -0
  24. data/ext/mkrf-rakehelper-monkey.rb +52 -0
  25. data/ext/mkrf_conf.rb +3 -0
  26. data/ext/opencv-ffi/.gitignore +4 -0
  27. data/ext/opencv-ffi/matcher_helper.cpp +56 -0
  28. data/ext/opencv-ffi/mkrf_conf.rb +12 -0
  29. data/ext/opencv-ffi/vector_math.cpp +39 -0
  30. data/ext/opensurf/.gitignore +4 -0
  31. data/ext/opensurf/README +38 -0
  32. data/ext/opensurf/fasthessian.cpp +376 -0
  33. data/ext/opensurf/fasthessian.h +108 -0
  34. data/ext/opensurf/integral.cpp +58 -0
  35. data/ext/opensurf/integral.h +55 -0
  36. data/ext/opensurf/ipoint.cpp +108 -0
  37. data/ext/opensurf/ipoint.h +76 -0
  38. data/ext/opensurf/kmeans.h +172 -0
  39. data/ext/opensurf/mkrf_conf.rb +10 -0
  40. data/ext/opensurf/responselayer.h +92 -0
  41. data/ext/opensurf/surf.cpp +317 -0
  42. data/ext/opensurf/surf.h +66 -0
  43. data/ext/opensurf/surflib.cpp +98 -0
  44. data/ext/opensurf/surflib.h +96 -0
  45. data/ext/opensurf/utils.cpp +357 -0
  46. data/ext/opensurf/utils.h +63 -0
  47. data/lib/.gitignore +1 -0
  48. data/lib/opencv-ffi-ext/eigen.rb +84 -0
  49. data/lib/opencv-ffi-ext/features2d.rb +4 -0
  50. data/lib/opencv-ffi-ext/matcher_helper.rb +24 -0
  51. data/lib/opencv-ffi-ext/opensurf.rb +217 -0
  52. data/lib/opencv-ffi-ext/sift.rb +118 -0
  53. data/lib/opencv-ffi-ext/vector_math.rb +115 -0
  54. data/lib/opencv-ffi-wrappers.rb +7 -0
  55. data/lib/opencv-ffi-wrappers/core.rb +24 -0
  56. data/lib/opencv-ffi-wrappers/core/iplimage.rb +50 -0
  57. data/lib/opencv-ffi-wrappers/core/mat.rb +268 -0
  58. data/lib/opencv-ffi-wrappers/core/misc_draw.rb +44 -0
  59. data/lib/opencv-ffi-wrappers/core/point.rb +286 -0
  60. data/lib/opencv-ffi-wrappers/core/rect.rb +40 -0
  61. data/lib/opencv-ffi-wrappers/core/scalar.rb +104 -0
  62. data/lib/opencv-ffi-wrappers/core/size.rb +88 -0
  63. data/lib/opencv-ffi-wrappers/enumerable.rb +10 -0
  64. data/lib/opencv-ffi-wrappers/features2d.rb +17 -0
  65. data/lib/opencv-ffi-wrappers/features2d/image_patch.rb +322 -0
  66. data/lib/opencv-ffi-wrappers/features2d/star.rb +111 -0
  67. data/lib/opencv-ffi-wrappers/features2d/surf.rb +115 -0
  68. data/lib/opencv-ffi-wrappers/highgui.rb +10 -0
  69. data/lib/opencv-ffi-wrappers/imgproc.rb +4 -0
  70. data/lib/opencv-ffi-wrappers/imgproc/features.rb +35 -0
  71. data/lib/opencv-ffi-wrappers/imgproc/geometric.rb +39 -0
  72. data/lib/opencv-ffi-wrappers/matcher.rb +297 -0
  73. data/lib/opencv-ffi-wrappers/matrix.rb +37 -0
  74. data/lib/opencv-ffi-wrappers/misc.rb +41 -0
  75. data/lib/opencv-ffi-wrappers/misc/params.rb +34 -0
  76. data/lib/opencv-ffi-wrappers/sequence.rb +37 -0
  77. data/lib/opencv-ffi-wrappers/vectors.rb +38 -0
  78. data/lib/opencv-ffi.rb +12 -0
  79. data/lib/opencv-ffi/calib3d.rb +26 -0
  80. data/lib/opencv-ffi/core.rb +15 -0
  81. data/lib/opencv-ffi/core/draw.rb +68 -0
  82. data/lib/opencv-ffi/core/dynamic.rb +13 -0
  83. data/lib/opencv-ffi/core/library.rb +5 -0
  84. data/lib/opencv-ffi/core/operations.rb +122 -0
  85. data/lib/opencv-ffi/core/point.rb +22 -0
  86. data/lib/opencv-ffi/core/types.rb +172 -0
  87. data/lib/opencv-ffi/cvffi.rb +8 -0
  88. data/lib/opencv-ffi/features2d.rb +7 -0
  89. data/lib/opencv-ffi/features2d/library.rb +6 -0
  90. data/lib/opencv-ffi/features2d/star.rb +30 -0
  91. data/lib/opencv-ffi/features2d/surf.rb +38 -0
  92. data/lib/opencv-ffi/highgui.rb +31 -0
  93. data/lib/opencv-ffi/imgproc.rb +9 -0
  94. data/lib/opencv-ffi/imgproc/features.rb +37 -0
  95. data/lib/opencv-ffi/imgproc/geometric.rb +42 -0
  96. data/lib/opencv-ffi/imgproc/library.rb +6 -0
  97. data/lib/opencv-ffi/imgproc/misc.rb +39 -0
  98. data/lib/opencv-ffi/version.rb +3 -0
  99. data/opencv-ffi.gemspec +26 -0
  100. data/test/core/test_draw.rb +46 -0
  101. data/test/core/test_operations.rb +135 -0
  102. data/test/core/test_size.rb +14 -0
  103. data/test/core/test_text.rb +52 -0
  104. data/test/ext/test_eigen.rb +105 -0
  105. data/test/ext/test_opensurf.rb +35 -0
  106. data/test/ext/test_sift.rb +26 -0
  107. data/test/ext/test_vector_math.rb +85 -0
  108. data/test/features2d/test_surf.rb +63 -0
  109. data/test/imgproc/test_goodfeatures.rb +18 -0
  110. data/test/setup.rb +65 -0
  111. data/test/test_calib3d.rb +38 -0
  112. data/test/test_core.rb +26 -0
  113. data/test/test_ext.rb +8 -0
  114. data/test/test_features2d.rb +9 -0
  115. data/test/test_files/images/IMG_7088.JPG +0 -0
  116. data/test/test_files/images/IMG_7088_small.JPG +0 -0
  117. data/test/test_files/images/IMG_7089.JPG +0 -0
  118. data/test/test_highgui.rb +26 -0
  119. data/test/test_imgproc.rb +35 -0
  120. data/test/test_wrappers.rb +8 -0
  121. data/test/wrappers/core/test_draw.rb +41 -0
  122. data/test/wrappers/core/test_mat.rb +40 -0
  123. data/test/wrappers/core/test_operations.rb +35 -0
  124. data/test/wrappers/core/test_types.rb +235 -0
  125. data/test/wrappers/features2d/test_image_patch.rb +108 -0
  126. data/test/wrappers/test_imgproc.rb +87 -0
  127. data/test/wrappers/test_matcher.rb +96 -0
  128. data/test/wrappers/test_star.rb +28 -0
  129. data/test/wrappers/test_surf.rb +36 -0
  130. metadata +234 -0
@@ -0,0 +1,98 @@
1
+
2
+ #include <opencv2/core/types_c.h>
3
+ #include <opencv2/features2d/features2d.hpp>
4
+ #include "surflib.h"
5
+
6
+ #include <stdio.h>
7
+
8
+ typedef struct {
9
+ char upright;
10
+ int octaves, intervals, init_sample;
11
+ float thres;
12
+ } OpenSURFParams_t;
13
+
14
+ typedef struct {
15
+ CvPoint pt;
16
+ float scale;
17
+ float orientation;
18
+ int laplacian;
19
+ float descriptor[64];
20
+ } OpenSURFPoint_t;
21
+
22
+ /* "constructor" for OpenSURFPoint_t */
23
+
24
+ /* Ape the existing OpenCV interface a bit... */
25
+ extern "C"
26
+ CvSeq *openSurfDetect( IplImage *img,
27
+ CvMemStorage *storage,
28
+ OpenSURFParams_t params )
29
+ {
30
+ std::vector<Ipoint> ipts;
31
+
32
+ surfDet( img, ipts, params.octaves, params.intervals, params.init_sample, params.thres );
33
+
34
+ /* Now unpack the ipts to keypoints */
35
+ CvSeq *points = cvCreateSeq( 0, sizeof(CvSeq), sizeof(OpenSURFPoint_t), storage );
36
+
37
+ for( std::vector<Ipoint>::iterator i = ipts.begin(); i != ipts.end(); i++ ) {
38
+ // TODO. Impedence mismatch trying to match CVSurf's "size" and "hessian"
39
+ OpenSURFPoint_t point;
40
+ point.pt.x = (*i).x;
41
+ point.pt.y = (*i).y;
42
+ point.scale = (*i).scale;
43
+ point.orientation = (*i).orientation;
44
+ point.laplacian = (*i).laplacian;
45
+
46
+ cvSeqPush( points, &point );
47
+ }
48
+
49
+ return points;
50
+ }
51
+
52
+
53
+ extern "C"
54
+ CvSeq *openSurfDescribe( IplImage *img, CvSeq *points,
55
+ OpenSURFParams_t params )
56
+ {
57
+ /* Repack the CvSeq to ipts */
58
+ std::vector<Ipoint> ipts;
59
+
60
+ CvSeqReader reader;
61
+ cvStartReadSeq( points, &reader, 0 );
62
+ for( int i = 0; i < points->total; i++ ) {
63
+ OpenSURFPoint_t *point = (OpenSURFPoint_t *)reader.ptr;
64
+ Ipoint ip;
65
+
66
+ ip.x = point->pt.x;
67
+ ip.y = point->pt.y;
68
+ ip.scale = point->scale;
69
+ ip.orientation = point->orientation;
70
+ ip.laplacian = point->laplacian;
71
+
72
+ ipts.push_back(ip);
73
+
74
+ CV_NEXT_SEQ_ELEM( points->elem_size, reader );
75
+ }
76
+
77
+ surfDes( img, ipts, params.upright );
78
+
79
+ for(unsigned int i = 0; i < ipts.size(); i++ ) {
80
+ Ipoint pt( ipts[i] );
81
+ OpenSURFPoint_t *point = (OpenSURFPoint_t *)cvGetSeqElem( points, i );
82
+ point->pt.x = pt.x;
83
+ point->pt.y = pt.y;
84
+ point->scale = pt.scale;
85
+ point->orientation = pt.orientation;
86
+ point->laplacian = pt.laplacian;
87
+ memcpy( point->descriptor, pt.descriptor, sizeof(float)*64 );
88
+ }
89
+
90
+ return points;
91
+ }
92
+
93
+ extern "C"
94
+ CvSeq *createOpenSURFPointSequence( CvMemStorage *storage )
95
+ {
96
+ return cvCreateSeq( 0, sizeof(CvSeq), sizeof(OpenSURFPoint_t), storage );
97
+ }
98
+
@@ -0,0 +1,96 @@
1
+ /***********************************************************
2
+ * --- OpenSURF --- *
3
+ * This library is distributed under the GNU GPL. Please *
4
+ * use the contact form at http://www.chrisevansdev.com *
5
+ * for more information. *
6
+ * *
7
+ * C. Evans, Research Into Robust Visual Features, *
8
+ * MSc University of Bristol, 2008. *
9
+ * *
10
+ ************************************************************/
11
+
12
+ #ifndef SURFLIB_H
13
+ #define SURFLIB_H
14
+
15
+ #include <opencv2/core/core.hpp>
16
+
17
+ #include "integral.h"
18
+ #include "fasthessian.h"
19
+ #include "surf.h"
20
+ #include "ipoint.h"
21
+ #include "utils.h"
22
+
23
+
24
+ //! Library function builds vector of described interest points
25
+ inline void surfDetDes(IplImage *img, /* image to find Ipoints in */
26
+ std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */
27
+ bool upright = false, /* run in rotation invariant mode? */
28
+ int octaves = OCTAVES, /* number of octaves to calculate */
29
+ int intervals = INTERVALS, /* number of intervals per octave */
30
+ int init_sample = INIT_SAMPLE, /* initial sampling step */
31
+ float thres = THRES /* blob response threshold */)
32
+ {
33
+ // Create integral-image representation of the image
34
+ IplImage *int_img = Integral(img);
35
+
36
+ // Create Fast Hessian Object
37
+ FastHessian fh(int_img, ipts, octaves, intervals, init_sample, thres);
38
+
39
+ // Extract interest points and store in vector ipts
40
+ fh.getIpoints();
41
+
42
+ // Create Surf Descriptor Object
43
+ Surf des(int_img, ipts);
44
+
45
+ // Extract the descriptors for the ipts
46
+ des.getDescriptors(upright);
47
+
48
+ // Deallocate the integral image
49
+ cvReleaseImage(&int_img);
50
+ }
51
+
52
+
53
+ //! Library function builds vector of interest points
54
+ inline void surfDet(IplImage *img, /* image to find Ipoints in */
55
+ std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */
56
+ int octaves = OCTAVES, /* number of octaves to calculate */
57
+ int intervals = INTERVALS, /* number of intervals per octave */
58
+ int init_sample = INIT_SAMPLE, /* initial sampling step */
59
+ float thres = THRES /* blob response threshold */)
60
+ {
61
+ // Create integral image representation of the image
62
+ IplImage *int_img = Integral(img);
63
+
64
+ // Create Fast Hessian Object
65
+ FastHessian fh(int_img, ipts, octaves, intervals, init_sample, thres);
66
+
67
+ // Extract interest points and store in vector ipts
68
+ fh.getIpoints();
69
+
70
+ // Deallocate the integral image
71
+ cvReleaseImage(&int_img);
72
+ }
73
+
74
+
75
+
76
+
77
+ //! Library function describes interest points in vector
78
+ inline void surfDes(IplImage *img, /* image to find Ipoints in */
79
+ std::vector<Ipoint> &ipts, /* reference to vector of Ipoints */
80
+ bool upright = false) /* run in rotation invariant mode? */
81
+ {
82
+ // Create integral image representation of the image
83
+ IplImage *int_img = Integral(img);
84
+
85
+ // Create Surf Descriptor Object
86
+ Surf des(int_img, ipts);
87
+
88
+ // Extract the descriptors for the ipts
89
+ des.getDescriptors(upright);
90
+
91
+ // Deallocate the integral image
92
+ cvReleaseImage(&int_img);
93
+ }
94
+
95
+
96
+ #endif
@@ -0,0 +1,357 @@
1
+ /***********************************************************
2
+ * --- OpenSURF --- *
3
+ * This library is distributed under the GNU GPL. Please *
4
+ * use the contact form at http://www.chrisevansdev.com *
5
+ * for more information. *
6
+ * *
7
+ * C. Evans, Research Into Robust Visual Features, *
8
+ * MSc University of Bristol, 2008. *
9
+ * *
10
+ ************************************************************/
11
+
12
+ #include <opencv2/highgui/highgui_c.h>
13
+ #include <opencv2/core/core_c.h>
14
+ #include <opencv2/imgproc/imgproc_c.h>
15
+ #include <iostream>
16
+ #include <fstream>
17
+ #include <time.h>
18
+
19
+ #include "utils.h"
20
+
21
+ using namespace std;
22
+
23
+ //-------------------------------------------------------
24
+
25
+ static const int NCOLOURS = 8;
26
+ static const CvScalar COLOURS [] = {cvScalar(255,0,0), cvScalar(0,255,0),
27
+ cvScalar(0,0,255), cvScalar(255,255,0),
28
+ cvScalar(0,255,255), cvScalar(255,0,255),
29
+ cvScalar(255,255,255), cvScalar(0,0,0)};
30
+
31
+ //-------------------------------------------------------
32
+
33
+ //! Display error message and terminate program
34
+ void error(const char *msg)
35
+ {
36
+ cout << "\nError: " << msg;
37
+ getchar();
38
+ exit(0);
39
+ }
40
+
41
+ //-------------------------------------------------------
42
+
43
+ //! Show the provided image and wait for keypress
44
+ void showImage(const IplImage *img)
45
+ {
46
+ cvNamedWindow("Surf", CV_WINDOW_AUTOSIZE);
47
+ cvShowImage("Surf", img);
48
+ cvWaitKey(0);
49
+ }
50
+
51
+ //-------------------------------------------------------
52
+
53
+ //! Show the provided image in titled window and wait for keypress
54
+ void showImage(char *title,const IplImage *img)
55
+ {
56
+ cvNamedWindow(title, CV_WINDOW_AUTOSIZE);
57
+ cvShowImage(title, img);
58
+ cvWaitKey(0);
59
+ }
60
+
61
+ //-------------------------------------------------------
62
+
63
+ // Convert image to single channel 32F
64
+ IplImage *getGray(const IplImage *img)
65
+ {
66
+ // Check we have been supplied a non-null img pointer
67
+ if (!img) error("Unable to create grayscale image. No image supplied");
68
+
69
+ IplImage* gray8, * gray32;
70
+
71
+ gray32 = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
72
+
73
+ if( img->nChannels == 1 )
74
+ gray8 = (IplImage *) cvClone( img );
75
+ else {
76
+ gray8 = cvCreateImage( cvGetSize(img), IPL_DEPTH_8U, 1 );
77
+ cvCvtColor( img, gray8, CV_BGR2GRAY );
78
+ }
79
+
80
+ cvConvertScale( gray8, gray32, 1.0 / 255.0, 0 );
81
+
82
+ cvReleaseImage( &gray8 );
83
+ return gray32;
84
+ }
85
+
86
+ //-------------------------------------------------------
87
+
88
+ //! Draw all the Ipoints in the provided vector
89
+ void drawIpoints(IplImage *img, vector<Ipoint> &ipts, int tailSize)
90
+ {
91
+ Ipoint *ipt;
92
+ float s, o;
93
+ int r1, c1, r2, c2, lap;
94
+
95
+ for(unsigned int i = 0; i < ipts.size(); i++)
96
+ {
97
+ ipt = &ipts.at(i);
98
+ s = (2.5f * ipt->scale);
99
+ o = ipt->orientation;
100
+ lap = ipt->laplacian;
101
+ r1 = fRound(ipt->y);
102
+ c1 = fRound(ipt->x);
103
+ c2 = fRound(s * cos(o)) + c1;
104
+ r2 = fRound(s * sin(o)) + r1;
105
+
106
+ if (o) // Green line indicates orientation
107
+ cvLine(img, cvPoint(c1, r1), cvPoint(c2, r2), cvScalar(0, 255, 0));
108
+ else // Green dot if using upright version
109
+ cvCircle(img, cvPoint(c1,r1), 1, cvScalar(0, 255, 0),-1);
110
+
111
+ if (lap == 1)
112
+ { // Blue circles indicate dark blobs on light backgrounds
113
+ cvCircle(img, cvPoint(c1,r1), fRound(s), cvScalar(255, 0, 0),1);
114
+ }
115
+ else if (lap == 0)
116
+ { // Red circles indicate light blobs on dark backgrounds
117
+ cvCircle(img, cvPoint(c1,r1), fRound(s), cvScalar(0, 0, 255),1);
118
+ }
119
+ else if (lap == 9)
120
+ { // Red circles indicate light blobs on dark backgrounds
121
+ cvCircle(img, cvPoint(c1,r1), fRound(s), cvScalar(0, 255, 0),1);
122
+ }
123
+
124
+ // Draw motion from ipoint dx and dy
125
+ if (tailSize)
126
+ {
127
+ cvLine(img, cvPoint(c1,r1),
128
+ cvPoint(int(c1+ipt->dx*tailSize), int(r1+ipt->dy*tailSize)),
129
+ cvScalar(255,255,255), 1);
130
+ }
131
+ }
132
+ }
133
+
134
+ //-------------------------------------------------------
135
+
136
+ //! Draw a single feature on the image
137
+ void drawIpoint(IplImage *img, Ipoint &ipt, int tailSize)
138
+ {
139
+ float s, o;
140
+ int r1, c1, r2, c2, lap;
141
+
142
+ s = (2.5f * ipt.scale);
143
+ o = ipt.orientation;
144
+ lap = ipt.laplacian;
145
+ r1 = fRound(ipt.y);
146
+ c1 = fRound(ipt.x);
147
+
148
+ // Green line indicates orientation
149
+ if (o) // Green line indicates orientation
150
+ {
151
+ c2 = fRound(s * cos(o)) + c1;
152
+ r2 = fRound(s * sin(o)) + r1;
153
+ cvLine(img, cvPoint(c1, r1), cvPoint(c2, r2), cvScalar(0, 255, 0));
154
+ }
155
+ else // Green dot if using upright version
156
+ cvCircle(img, cvPoint(c1,r1), 1, cvScalar(0, 255, 0),-1);
157
+
158
+ if (lap >= 0)
159
+ { // Blue circles indicate light blobs on dark backgrounds
160
+ cvCircle(img, cvPoint(c1,r1), fRound(s), cvScalar(255, 0, 0),1);
161
+ }
162
+ else
163
+ { // Red circles indicate light blobs on dark backgrounds
164
+ cvCircle(img, cvPoint(c1,r1), fRound(s), cvScalar(0, 0, 255),1);
165
+ }
166
+
167
+ // Draw motion from ipoint dx and dy
168
+ if (tailSize)
169
+ {
170
+ cvLine(img, cvPoint(c1,r1),
171
+ cvPoint(int(c1+ipt.dx*tailSize), int(r1+ipt.dy*tailSize)),
172
+ cvScalar(255,255,255), 1);
173
+ }
174
+ }
175
+
176
+ //-------------------------------------------------------
177
+
178
+ //! Draw a single feature on the image
179
+ void drawPoint(IplImage *img, Ipoint &ipt)
180
+ {
181
+ float s, o;
182
+ int r1, c1;
183
+
184
+ s = 3;
185
+ o = ipt.orientation;
186
+ r1 = fRound(ipt.y);
187
+ c1 = fRound(ipt.x);
188
+
189
+ cvCircle(img, cvPoint(c1,r1), fRound(s), COLOURS[ipt.clusterIndex%NCOLOURS], -1);
190
+ cvCircle(img, cvPoint(c1,r1), fRound(s+1), COLOURS[(ipt.clusterIndex+1)%NCOLOURS], 2);
191
+
192
+ }
193
+
194
+ //-------------------------------------------------------
195
+
196
+ //! Draw a single feature on the image
197
+ void drawPoints(IplImage *img, vector<Ipoint> &ipts)
198
+ {
199
+ float s, o;
200
+ int r1, c1;
201
+
202
+ for(unsigned int i = 0; i < ipts.size(); i++)
203
+ {
204
+ s = 3;
205
+ o = ipts[i].orientation;
206
+ r1 = fRound(ipts[i].y);
207
+ c1 = fRound(ipts[i].x);
208
+
209
+ cvCircle(img, cvPoint(c1,r1), fRound(s), COLOURS[ipts[i].clusterIndex%NCOLOURS], -1);
210
+ cvCircle(img, cvPoint(c1,r1), fRound(s+1), COLOURS[(ipts[i].clusterIndex+1)%NCOLOURS], 2);
211
+ }
212
+ }
213
+
214
+ //-------------------------------------------------------
215
+
216
+ //! Draw descriptor windows around Ipoints in the provided vector
217
+ void drawWindows(IplImage *img, vector<Ipoint> &ipts)
218
+ {
219
+ Ipoint *ipt;
220
+ float s, o, cd, sd;
221
+ int x, y;
222
+ CvPoint2D32f src[4];
223
+
224
+ for(unsigned int i = 0; i < ipts.size(); i++)
225
+ {
226
+ ipt = &ipts.at(i);
227
+ s = (10 * ipt->scale);
228
+ o = ipt->orientation;
229
+ y = fRound(ipt->y);
230
+ x = fRound(ipt->x);
231
+ cd = cos(o);
232
+ sd = sin(o);
233
+
234
+ src[0].x=sd*s+cd*s+x; src[0].y=-cd*s+sd*s+y;
235
+ src[1].x=sd*s+cd*-s+x; src[1].y=-cd*s+sd*-s+y;
236
+ src[2].x=sd*-s+cd*-s+x; src[2].y=-cd*-s+sd*-s+y;
237
+ src[3].x=sd*-s+cd*s+x; src[3].y=-cd*-s+sd*s+y;
238
+
239
+ if (o) // Draw orientation line
240
+ cvLine(img, cvPoint(x, y),
241
+ cvPoint(fRound(s*cd + x), fRound(s*sd + y)), cvScalar(0, 255, 0),1);
242
+ else // Green dot if using upright version
243
+ cvCircle(img, cvPoint(x,y), 1, cvScalar(0, 255, 0),-1);
244
+
245
+
246
+ // Draw box window around the point
247
+ cvLine(img, cvPoint(fRound(src[0].x), fRound(src[0].y)),
248
+ cvPoint(fRound(src[1].x), fRound(src[1].y)), cvScalar(255, 0, 0),2);
249
+ cvLine(img, cvPoint(fRound(src[1].x), fRound(src[1].y)),
250
+ cvPoint(fRound(src[2].x), fRound(src[2].y)), cvScalar(255, 0, 0),2);
251
+ cvLine(img, cvPoint(fRound(src[2].x), fRound(src[2].y)),
252
+ cvPoint(fRound(src[3].x), fRound(src[3].y)), cvScalar(255, 0, 0),2);
253
+ cvLine(img, cvPoint(fRound(src[3].x), fRound(src[3].y)),
254
+ cvPoint(fRound(src[0].x), fRound(src[0].y)), cvScalar(255, 0, 0),2);
255
+
256
+ }
257
+ }
258
+
259
+ //-------------------------------------------------------
260
+
261
+ // Draw the FPS figure on the image (requires at least 2 calls)
262
+ void drawFPS(IplImage *img)
263
+ {
264
+ static int counter = 0;
265
+ static clock_t t;
266
+ static float fps;
267
+ char fps_text[20];
268
+ CvFont font;
269
+ cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, 1.0,1.0,0,2);
270
+
271
+ // Add fps figure (every 10 frames)
272
+ if (counter > 10)
273
+ {
274
+ fps = (10.0f/(clock()-t) * CLOCKS_PER_SEC);
275
+ t=clock();
276
+ counter = 0;
277
+ }
278
+
279
+ // Increment counter
280
+ ++counter;
281
+
282
+ // Get the figure as a string
283
+ sprintf(fps_text,"FPS: %.2f",fps);
284
+
285
+ // Draw the string on the image
286
+ cvPutText (img,fps_text,cvPoint(10,25), &font, cvScalar(255,255,0));
287
+ }
288
+
289
+ //-------------------------------------------------------
290
+
291
+ //! Save the SURF features to file
292
+ void saveSurf(char *filename, vector<Ipoint> &ipts)
293
+ {
294
+ ofstream outfile(filename);
295
+
296
+ // output descriptor length
297
+ outfile << "64\n";
298
+ outfile << ipts.size() << "\n";
299
+
300
+ // create output line as: scale x y des
301
+ for(unsigned int i=0; i < ipts.size(); i++)
302
+ {
303
+ outfile << ipts.at(i).scale << " ";
304
+ outfile << ipts.at(i).x << " ";
305
+ outfile << ipts.at(i).y << " ";
306
+ outfile << ipts.at(i).orientation << " ";
307
+ outfile << ipts.at(i).laplacian << " ";
308
+ outfile << ipts.at(i).scale << " ";
309
+ for(int j=0; j<64; j++)
310
+ outfile << ipts.at(i).descriptor[j] << " ";
311
+
312
+ outfile << "\n";
313
+ }
314
+
315
+ outfile.close();
316
+ }
317
+
318
+ //-------------------------------------------------------
319
+
320
+ //! Load the SURF features from file
321
+ void loadSurf(char *filename, vector<Ipoint> &ipts)
322
+ {
323
+ int descriptorLength, count;
324
+ ifstream infile(filename);
325
+
326
+ // clear the ipts vector first
327
+ ipts.clear();
328
+
329
+ // read descriptor length/number of ipoints
330
+ infile >> descriptorLength;
331
+ infile >> count;
332
+
333
+ // for each ipoint
334
+ for (int i = 0; i < count; i++)
335
+ {
336
+ Ipoint ipt;
337
+
338
+ // read vals
339
+ infile >> ipt.scale;
340
+ infile >> ipt.x;
341
+ infile >> ipt.y;
342
+ infile >> ipt.orientation;
343
+ infile >> ipt.laplacian;
344
+ infile >> ipt.scale;
345
+
346
+ // read descriptor components
347
+ for (int j = 0; j < 64; j++)
348
+ infile >> ipt.descriptor[j];
349
+
350
+ ipts.push_back(ipt);
351
+
352
+ }
353
+ }
354
+
355
+ //-------------------------------------------------------
356
+
357
+ //-------------------------------------------------------