opencv-ffi 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ //-------------------------------------------------------