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,63 @@
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 UTILS_H
13
+ #define UTILS_H
14
+
15
+ #include <opencv2/core/core.hpp>
16
+ #include "ipoint.h"
17
+
18
+ #include <vector>
19
+
20
+
21
+ //! Display error message and terminate program
22
+ void error(const char *msg);
23
+
24
+ //! Show the provided image and wait for keypress
25
+ void showImage(const IplImage *img);
26
+
27
+ //! Show the provided image in titled window and wait for keypress
28
+ void showImage(char *title,const IplImage *img);
29
+
30
+ // Convert image to single channel 32F
31
+ IplImage* getGray(const IplImage *img);
32
+
33
+ //! Draw a single feature on the image
34
+ void drawIpoint(IplImage *img, Ipoint &ipt, int tailSize = 0);
35
+
36
+ //! Draw all the Ipoints in the provided vector
37
+ void drawIpoints(IplImage *img, std::vector<Ipoint> &ipts, int tailSize = 0);
38
+
39
+ //! Draw descriptor windows around Ipoints in the provided vector
40
+ void drawWindows(IplImage *img, std::vector<Ipoint> &ipts);
41
+
42
+ // Draw the FPS figure on the image (requires at least 2 calls)
43
+ void drawFPS(IplImage *img);
44
+
45
+ //! Draw a Point at feature location
46
+ void drawPoint(IplImage *img, Ipoint &ipt);
47
+
48
+ //! Draw a Point at all features
49
+ void drawPoints(IplImage *img, std::vector<Ipoint> &ipts);
50
+
51
+ //! Save the SURF features to file
52
+ void saveSurf(char *filename, std::vector<Ipoint> &ipts);
53
+
54
+ //! Load the SURF features from file
55
+ void loadSurf(char *filename, std::vector<Ipoint> &ipts);
56
+
57
+ //! Round float to nearest integer
58
+ inline int fRound(float flt)
59
+ {
60
+ return (int) floor(flt+0.5f);
61
+ }
62
+
63
+ #endif
@@ -0,0 +1 @@
1
+ *.so
@@ -0,0 +1,84 @@
1
+
2
+ require 'opencv-ffi'
3
+ require 'opencv-ffi-wrappers'
4
+
5
+ module CVFFI
6
+ module Eigen
7
+ extend NiceFFI::Library
8
+
9
+ libs_dir = File.dirname(__FILE__) + "/../../ext/eigen/"
10
+ pathset = NiceFFI::PathSet::DEFAULT.prepend( libs_dir )
11
+ load_library("cvffi_eigen", pathset)
12
+
13
+
14
+ ##--- SVD bits ---
15
+ class EigenSvdResults < NiceFFI::Struct
16
+ layout :D, CvMat.typed_pointer,
17
+ :U, CvMat.typed_pointer,
18
+ :V, CvMat.typed_pointer
19
+ end
20
+
21
+ attach_function :eigenSvdWithCvMat, [:pointer, :pointer, :uchar], :void
22
+
23
+ def self.svd( a, opts = {} )
24
+ thin = opts[:thin] ? 1 : 0
25
+
26
+ results = EigenSvdResults.new '\0'
27
+ eigenSvdWithCvMat( a.to_CvMat, results, thin )
28
+
29
+ [ results.U, results.D, results.V ]
30
+ end
31
+
32
+ ##-- Eigenvector solvers
33
+ class EigenDecompResults < NiceFFI::Struct
34
+ layout :D, CvMat.typed_pointer,
35
+ :V, CvMat.typed_pointer
36
+ end
37
+
38
+ attach_function :eigenDecompWithCvMat, [:pointer, :pointer], :void
39
+
40
+ def self.eigen( a )
41
+ results = EigenDecompResults.new '\0'
42
+ eigenDecompWithCvMat( a.to_CvMat, results )
43
+
44
+ [results.D, results.V]
45
+ end
46
+
47
+
48
+ ##--- Polynomial solver bits --
49
+ class Eigen7d <NiceFFI::Struct
50
+ layout :a, :double,
51
+ :b, :double,
52
+ :c, :double,
53
+ :d, :double,
54
+ :e, :double,
55
+ :f, :double,
56
+ :g, :double
57
+ end
58
+
59
+ class Eigen6d < NiceFFI::Struct
60
+ layout :a, :double,
61
+ :b, :double,
62
+ :c, :double,
63
+ :d, :double,
64
+ :e, :double,
65
+ :f, :double
66
+ end
67
+
68
+ attach_function :eigenPoly6Solver, [Eigen7d.by_value], Eigen6d.by_value
69
+
70
+ def self.polySolver( a )
71
+
72
+ case a.length
73
+ when 7 then
74
+ coeffs = Eigen7d.new( a )
75
+ answer = eigenPoly6Solver( coeffs )
76
+ else
77
+ raise "Can't solve polynomial with #{a.length} coefficients"
78
+ end
79
+
80
+ answer.to_ary
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,4 @@
1
+
2
+
3
+ require 'opencv-ffi-wrappers/features2d/image_patch'
4
+
@@ -0,0 +1,24 @@
1
+
2
+ require 'nice-ffi'
3
+ require 'opencv-ffi-wrappers/matcher'
4
+
5
+ module CVFFI
6
+ extend NiceFFI::Library
7
+
8
+ libs_dir = File.dirname(__FILE__) + "/../../ext/opencv-ffi/"
9
+ pathset = NiceFFI::PathSet::DEFAULT.prepend( libs_dir )
10
+ load_library("cvffi", pathset)
11
+
12
+ attach_function :computeReprojError, [:pointer, :pointer], :double
13
+ attach_function :computeSetReprojError, [:pointer, :pointer], :void
14
+
15
+ def self.compute_reproj_error( match, model )
16
+ computeReprojError( match, model.to_CvMat( :type => :CV_64F ) )
17
+ end
18
+
19
+ def self.compute_set_reproj_error( matchSet, model )
20
+ computeSetReprojError( matchSet, model.to_CvMat( :type => :CV_64F ) )
21
+ end
22
+ end
23
+
24
+
@@ -0,0 +1,217 @@
1
+
2
+ require 'nice-ffi'
3
+
4
+ require 'opencv-ffi-wrappers/features2d/surf'
5
+
6
+ module CVFFI
7
+ module OpenSURF
8
+ extend NiceFFI::Library
9
+
10
+ libs_dir = File.dirname(__FILE__) + "/../../ext/opensurf/"
11
+ pathset = NiceFFI::PathSet::DEFAULT.prepend( libs_dir )
12
+ load_library("cvffi_opensurf", pathset)
13
+
14
+ class OpenSURFParams < NiceFFI::Struct
15
+ layout :upright, :char,
16
+ :octaves, :int,
17
+ :intervals, :int,
18
+ :init_sample, :int,
19
+ :thres, :float
20
+ end
21
+
22
+ class OpenSURFPoint < NiceFFI::Struct
23
+ layout :pt, CvPoint,
24
+ :scale, :float,
25
+ :orientation, :float,
26
+ :laplacian, :int,
27
+ :descriptor, [ :float, 64 ]
28
+ end
29
+
30
+
31
+ # CvSeq *opensurfDet( IplImage *img,
32
+ # CvMemStorage *storage,
33
+ # CvSURFParams params )
34
+ attach_function :openSurfDetect, [ :pointer, :pointer, OpenSURFParams.by_value ], CvSeq.typed_pointer
35
+ attach_function :openSurfDescribe, [ :pointer, :pointer, OpenSURFParams.by_value ], CvSeq.typed_pointer
36
+ attach_function :createOpenSURFPointSequence, [:pointer ], CvSeq.typed_pointer
37
+
38
+ class Result
39
+ attr_accessor :kp
40
+ def initialize( kp )
41
+ @kp = CVFFI::OpenSURF::OpenSURFPoint.new(kp)
42
+ end
43
+
44
+ def pt; @kp.pt; end
45
+ def x; pt.x; end
46
+ def y; pt.y; end
47
+
48
+ def scale; @kp.scale; end
49
+ def laplacian; @kp.laplacian; end
50
+ def orientation; @kp.orientation; end
51
+ def descriptor; @kp.descriptor; end
52
+
53
+ def distance_to(b)
54
+ CVFFI::VectorMath::L2distance( @kp.descriptor, b.descriptor, 64 )
55
+ end
56
+
57
+ def to_vector
58
+ Vector.[]( x, y, 1 )
59
+ end
60
+
61
+ def to_Point
62
+ pt.to_Point
63
+ end
64
+
65
+ def packed_descriptor
66
+ [@kp.descriptor.to_a.pack('e64')].pack('m0')
67
+ end
68
+ end
69
+
70
+ class ResultArray
71
+ include Enumerable
72
+
73
+ attr_reader :kp, :pool
74
+
75
+ def initialize( kp, pool )
76
+ @kp = Sequence.new(kp)
77
+ @pool = pool
78
+ @results = Array.new( @kp.length )
79
+
80
+ destructor = Proc.new { poolPtr = FFI::MemoryPointer.new :pointer
81
+ poolPtr.putPointer( 0, @pool )
82
+ cvReleaseMemStorage( poolPtr ) }
83
+ ObjectSpace.define_finalizer( self, destructor )
84
+ end
85
+
86
+ def reset( kp )
87
+ @kp = Sequence.new(kp)
88
+ @pool = kp.storage
89
+ @results = Array.new( @kp.length )
90
+ self
91
+ end
92
+
93
+ def result(i)
94
+ @results[i] ||= Result.new( @kp[i] )
95
+ end
96
+
97
+ def each
98
+ @results.each_index { |i|
99
+ yield result(i)
100
+ }
101
+ end
102
+
103
+ def [](i)
104
+ result(i)
105
+ end
106
+
107
+ def size
108
+ @kp.size
109
+ end
110
+ alias :length :size
111
+
112
+ def to_CvSeq
113
+ @kp.seq
114
+ end
115
+
116
+ def mark_on_image( img, opts )
117
+ each { |r|
118
+ CVFFI::draw_circle( img, r.kp.pt, opts )
119
+ }
120
+ end
121
+
122
+ def to_a
123
+ Array.new( size ) { |i|
124
+ r = result(i)
125
+ [ r.x, r.y, r.scale, r.orientation, r.laplacian, r.packed_descriptor ]
126
+ }
127
+ end
128
+
129
+ def self.from_a( a )
130
+ a = YAML::load(a) if a.is_a? String
131
+ raise "Don't know what to do" unless a.is_a? Array
132
+
133
+ pool = CVFFI::cvCreateMemStorage(0)
134
+ cvseq = CVFFI::OpenSURF::createOpenSURFPointSequence( pool )
135
+ seq = Sequence.new cvseq
136
+
137
+ a.each { |r|
138
+ raise "Hm, not what I expected" unless r.length == 6
139
+ point = CVFFI::OpenSURF::OpenSURFPoint.new( '' )
140
+ # Hm, the embedded CvPoint buggers up initialization by hash
141
+ point.scale = r[2]
142
+ point.orientation = r[3]
143
+ point.laplacian = r[4]
144
+ d = r[5].unpack('m')[0].unpack('e64')
145
+
146
+ d.each_with_index { |d,i| point.descriptor[i] = d }
147
+
148
+ # r[5].unpack('e64')
149
+ point.pt.x = r[0]
150
+ point.pt.y = r[1]
151
+ seq.push( point )
152
+ }
153
+
154
+
155
+ ra = ResultArray.new( cvseq, pool )
156
+ end
157
+
158
+ end
159
+
160
+ class Params
161
+ DEFAULTS = { upright: 0,
162
+ octaves: 5,
163
+ intervals: 4,
164
+ thres: 0.0004,
165
+ init_sample: 2 }
166
+
167
+ def initialize( opts = {} )
168
+ @params = {}
169
+ DEFAULTS.keys.each { |k|
170
+ @params[k] = opts[k] || DEFAULTS[k]
171
+ }
172
+ end
173
+
174
+ def to_OpenSurfParams
175
+ OpenSURFParams.new( @params )
176
+ end
177
+
178
+ def to_hash
179
+ @params
180
+ end
181
+ end
182
+
183
+
184
+ # Detection sets x,y,scale, laplacian
185
+ def self.detect( img, params )
186
+ params = params.to_OpenSurfParams unless params.is_a?( OpenSURFParams )
187
+ raise ArgumentError unless params.is_a?( OpenSURFParams )
188
+
189
+ mem_storage = CVFFI::cvCreateMemStorage( 0 )
190
+
191
+ img = img.ensure_greyscale
192
+ kp = CVFFI::CvSeq.new openSurfDetect( img, mem_storage, params )
193
+
194
+ ResultArray.new( kp, mem_storage )
195
+ end
196
+
197
+ # Descriptor takes x,y, scale. Apparently not laplcian
198
+ # Sets orientation, descriptor
199
+ def self.describe( img, points, params )
200
+ params = params.to_OpenSurfParams unless params.is_a?( OpenSURFParams )
201
+ raise ArgumentError unless params.is_a?( OpenSURFParams )
202
+
203
+ img = img.ensure_greyscale
204
+
205
+ puts "Extracting #{points.length} features"
206
+
207
+ kp = points.to_CvSeq
208
+
209
+ openSurfDescribe( img, kp, params )
210
+
211
+ points.reset(kp)
212
+ points
213
+ end
214
+
215
+
216
+ end
217
+ end
@@ -0,0 +1,118 @@
1
+
2
+ require 'nice-ffi'
3
+
4
+ require 'opencv-ffi-wrappers/misc/params'
5
+
6
+ module CVFFI
7
+
8
+ module SIFT
9
+ extend NiceFFI::Library
10
+
11
+ libs_dir = File.dirname(__FILE__) + "/../../ext/aishack-sift/"
12
+ pathset = NiceFFI::PathSet::DEFAULT.prepend( libs_dir )
13
+ load_library("cvffi_sift", pathset)
14
+
15
+ class SiftParams < NiceFFI::Struct
16
+ layout :octaves, :int,
17
+ :intervals, :int
18
+ end
19
+
20
+ NUM_BINS = 36
21
+ class SiftKeypoint < NiceFFI::Struct
22
+ layout :x, :float,
23
+ :y, :float,
24
+ :mag, [:float, NUM_BINS],
25
+ :orien, [:float, NUM_BINS],
26
+ :num_bins, :uint,
27
+ :scale, :uint
28
+ end
29
+
30
+ FV_LENGTH = 128
31
+ class SiftDescriptor < NiceFFI::Struct
32
+ layout :x, :float,
33
+ :y, :float,
34
+ :fv, [:float, FV_LENGTH],
35
+ :fv_length, :uint
36
+ end
37
+
38
+ class SiftResults< NiceFFI::Struct
39
+ layout :kps, :pointer,
40
+ :descs, :pointer,
41
+ :len, :uint
42
+ end
43
+
44
+ class Results
45
+ attr_accessor :kps, :descs
46
+
47
+ def initialize( k, d )
48
+ @kps = k
49
+ @descs = d
50
+ end
51
+
52
+ def size
53
+ @kps.length
54
+ end
55
+ alias :length :size
56
+
57
+ def to_a
58
+ a = Array.new
59
+ a << Array.new( size ) { |i|
60
+ kp = kps[i]
61
+ [ kp.x, kp.y, kp.mag, kp.orien, kp.num_bins, kp.scale ]
62
+ }
63
+ a << Array.new( size ) { |i|
64
+ d = descs[i]
65
+ [d.x, d.y, d.fv, d.fv_length]
66
+ }
67
+ end
68
+
69
+ def self.from_a( a )
70
+ a = YAML::load(a) if a.is_a? String
71
+ raise "Don't know what to do" unless a.is_a? Array
72
+ raise "Result isn't a two-element array" unless a.length == 2
73
+
74
+ kps = a[0]
75
+ descs = a[1]
76
+ end
77
+
78
+ end
79
+
80
+ attach_function :siftDetectDescribe_real, :siftDetectDescribe, [ :pointer, SiftParams.by_value ], SiftResults.typed_pointer
81
+
82
+
83
+ class Params < CVFFI::Params
84
+ param :octaves, 4
85
+ param :intervals, 5
86
+
87
+ def to_SiftParams
88
+ SiftParams.new( octaves: octaves,
89
+ intervals: intervals )
90
+ end
91
+
92
+ end
93
+
94
+
95
+ def self.detect( image, params )
96
+ params = params.to_SiftParams unless params.is_a?( SiftParams )
97
+
98
+ puts "Running SIFT algorithm with #{params.octaves} octaves and #{params.intervals} intervals."
99
+
100
+ kps = siftDetectDescribe_real( image, params )
101
+
102
+ # Unwrap the SiftKeypoints to an Array.
103
+ keypoints = Array.new( kps.len ) { |i|
104
+ SiftKeypoint.new( kps.kps + (i*SiftKeypoint.size))
105
+ }
106
+ descs = Array.new( kps.len ) { |i|
107
+ SiftDescriptor.new( kps.descs + (i*SiftDescriptor.size) )
108
+ }
109
+
110
+ p keypoints[0]
111
+ p descs[0]
112
+
113
+ Results.new( keypoints, descs )
114
+ end
115
+
116
+
117
+ end
118
+ end