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,115 @@
1
+
2
+ require 'nice-ffi'
3
+ require 'opencv-ffi-wrappers/vectors'
4
+
5
+ module CVFFI
6
+ module VectorMath
7
+ extend NiceFFI::Library
8
+
9
+ libs_dir = File.dirname(__FILE__) + "/../../ext/opencv-ffi/"
10
+ pathset = NiceFFI::PathSet::DEFAULT.prepend( libs_dir )
11
+ load_library("cvffi", pathset)
12
+
13
+
14
+ module NativeVectors
15
+ def self.included( base )
16
+ base.extend( ClassMethods)
17
+ end
18
+
19
+ module ClassMethods
20
+ def define_vector( type, length, name = nil )
21
+ name = name || "#{type}_#{length}_vector"
22
+ class_eval <<-eos
23
+ class #{name} < NiceFFI::Struct
24
+ layout :d, [:#{type}, #{length}]
25
+ def length; #{length}; end
26
+ end
27
+ eos
28
+ name
29
+ end
30
+ end
31
+
32
+ class ScalarVector
33
+
34
+ def define_vector( type, length, name = nil )
35
+ name = name || "Auto_#{type}_#{length}_vector"
36
+ instance_eval <<-eos
37
+ class #{name} < NiceFFI::Struct
38
+ layout :d, [:#{type}, #{length}]
39
+ def length; #{length}; end
40
+ end
41
+ eos
42
+ name
43
+ end
44
+
45
+ attr_accessor :data
46
+ def initialize( type, length )
47
+ name = define_vector( type, length )
48
+ instance_eval "@data = #{name}.new '\0'"
49
+ end
50
+
51
+ def [](i)
52
+ @data.d[i]
53
+ end
54
+
55
+ def []=(i,b)
56
+ @data.d[i] = b
57
+ end
58
+
59
+ def as_ScalarArray
60
+ ScalarArray.new( len: @data.length,
61
+ data: @data )
62
+ end
63
+ alias :to_c :as_ScalarArray
64
+
65
+ end
66
+ end
67
+
68
+
69
+
70
+ class UcharArray < NiceFFI::Struct
71
+ layout :len, :uint,
72
+ :data, :pointer
73
+ end
74
+
75
+ class ScalarArray < NiceFFI::Struct
76
+ layout :len, :uint,
77
+ :data, :pointer
78
+ end
79
+
80
+ attach_function :L2distance_32f, [:pointer, :pointer, :int], :float
81
+ attach_function :realL2distance_8u, :L2distance_8u, [UcharArray.by_value, UcharArray.by_value], :float
82
+
83
+ def self.L2distance( a,b, len = nil)
84
+ len ||= a.length
85
+ L2distance_32f( a, b, len )
86
+ end
87
+
88
+ def self.uchar_array_cast( a )
89
+ case a
90
+ when UcharArray
91
+ a
92
+ else
93
+ d = FFI::MemoryPointer.new :uint8, a.length
94
+ d.write_array_of_uint8( a )
95
+ #d.write_array_of_uint8( a.map{ |a| [[ a.to_i, 0 ].max, 255].min } )
96
+ UcharArray.new( len: a.length, data: d )
97
+ #else
98
+ # raise "Can't convert type #{a} to a uchar_array"
99
+ end
100
+ end
101
+
102
+ def self.L2distance_8u( a,b )
103
+ ## Allow for some dynamic repacking
104
+ raise "Arrays not same length" unless a.length == b.length
105
+ a = uchar_array_cast( a )
106
+ b = uchar_array_cast( b )
107
+
108
+ realL2distance_8u( a, b )
109
+ end
110
+ end
111
+
112
+
113
+ end
114
+
115
+
@@ -0,0 +1,7 @@
1
+
2
+ require 'opencv-ffi-wrappers/core'
3
+ require 'opencv-ffi-wrappers/matcher'
4
+ require 'opencv-ffi-wrappers/misc'
5
+ require 'opencv-ffi-wrappers/highgui'
6
+ require 'opencv-ffi-wrappers/imgproc'
7
+ require 'opencv-ffi-wrappers/features2d'
@@ -0,0 +1,24 @@
1
+
2
+ require 'opencv-ffi-wrappers/core/mat'
3
+ require 'opencv-ffi-wrappers/core/size'
4
+ require 'opencv-ffi-wrappers/core/point'
5
+ require 'opencv-ffi-wrappers/core/iplimage'
6
+ require 'opencv-ffi-wrappers/core/scalar'
7
+ require 'opencv-ffi-wrappers/core/rect'
8
+ require 'opencv-ffi-wrappers/core/misc_draw'
9
+
10
+ require 'opencv-ffi-wrappers/matrix'
11
+
12
+ require 'opencv-ffi/core'
13
+
14
+
15
+ module CVFFI
16
+ def self.solveCubic( coeffs )
17
+ roots = CVFFI::CvMat.new CVFFI::cvCreateMat( 1,3, :CV_32F )
18
+
19
+ CVFFI::cvSolveCubic( coeffs.to_CvMat, roots )
20
+
21
+ roots.coerce( coeffs )[1]
22
+ end
23
+ end
24
+
@@ -0,0 +1,50 @@
1
+
2
+ require 'opencv-ffi/core/types'
3
+ require 'opencv-ffi-wrappers/core'
4
+
5
+ module CVFFI
6
+
7
+ module IplImageFunctions
8
+ def image_size
9
+ Size.new( self.width, self.height )
10
+ end
11
+
12
+ def to_IplImage
13
+ self
14
+ end
15
+
16
+ def clone
17
+ CVFFI::IplImage.new CVFFI::cvCloneImage( self )
18
+ end
19
+
20
+ def twin( *opts )
21
+ depth,nChannels = if opts[0].is_a? Hash
22
+ opts = opts.pop
23
+ [opts[:depth], opts[:channels]]
24
+ else
25
+ opts
26
+ end
27
+
28
+ depth ||= self.depth
29
+ nChannels ||= self.nChannels
30
+ CVFFI::IplImage.new CVFFI::cvCreateImage( self.image_size.to_CvSize, depth, nChannels )
31
+ end
32
+
33
+ def ensure_greyscale
34
+ return self if nChannels == 1
35
+
36
+ greyImg = CVFFI::cvCreateImage( CVFFI::CvSize.new( { :height => height,
37
+ :width => width }),
38
+ :IPL_DEPTH_8U, 1 )
39
+ CVFFI::cvCvtColor( self.to_IplImage, greyImg, :CV_BGR2GRAY )
40
+ greyImg
41
+ end
42
+ alias :ensure_grayscale :ensure_greyscale
43
+ end
44
+
45
+ class IplImage
46
+ include IplImageFunctions
47
+ end
48
+
49
+
50
+ end
@@ -0,0 +1,268 @@
1
+ require 'opencv-ffi/core/types'
2
+ require 'opencv-ffi-wrappers/core'
3
+ require 'opencv-ffi-wrappers/misc'
4
+
5
+ require 'matrix'
6
+
7
+
8
+ # Monkey with Matrix and Vector's coercion functions
9
+ class Vector
10
+ alias :coerce_orig :coerce
11
+ def coerce(other)
12
+ case other
13
+ when CvMat
14
+ nil
15
+ else
16
+ coerce_orig(other)
17
+ end
18
+ end
19
+ end
20
+
21
+ module CVFFI
22
+
23
+ module CvMatFunctions
24
+ def self.included(base)
25
+ base.extend(ClassMethods)
26
+ end
27
+
28
+ # This is the somewhat funny Matrix format for coerce
29
+ # which returns the template class as well as the coerced version
30
+ # of the matrix
31
+ def coerce( other )
32
+ case other
33
+ when Matrix
34
+ [other, to_Matrix]
35
+ when Vector
36
+ [other, to_Vector]
37
+ else
38
+ raise TypeError, "#{self.class} can't be coerced into #{other.class}, fool"
39
+ end
40
+ end
41
+
42
+
43
+ def to_CvMat( opt = {} )
44
+ if opt[:type]
45
+ raise "Need to convert CvMat types" if opt[:type] != type
46
+ end
47
+ self
48
+ end
49
+
50
+ def to_Matrix
51
+ Matrix.build( height, width ) { |i,j|
52
+ at_f(i,j)
53
+ }
54
+ end
55
+
56
+ def to_ScalarMatrix
57
+ ScalarMatrix.rows Array.new( height ) { |y|
58
+ Array.new( width ) { |x|
59
+ d = CVFFI::cvGet2D( self, y,x )
60
+ d.w
61
+ }
62
+ }
63
+ end
64
+
65
+ def to_Vector
66
+ to_Matrix if height > 1 and width > 1
67
+ a = []
68
+ if height == 1
69
+ a = Array.new( width ) { |i| at_f(0,i) }
70
+ else
71
+ a = Array.new( height ) { |i| at_f(i,0) }
72
+ end
73
+ Vector[*a]
74
+ end
75
+
76
+ def to_a
77
+ to_Vector.to_a
78
+ end
79
+
80
+ # This is somewhat awkward because the FFI::Struct-iness of
81
+ # CvMat uses the Array-like API calls (at, [], size, etc)
82
+ def at_f(i,j)
83
+ CVFFI::cvGetReal2D( self, i, j )
84
+ end
85
+
86
+ def set_f( i,j, f )
87
+ CVFFI::cvSetReal2D( self, i, j, f )
88
+ end
89
+
90
+ def at_scalar(i,j)
91
+ CVFFI::cvGet2D( self, i, j )
92
+ end
93
+
94
+ def set_scalar( i,j, f )
95
+ CVFFI::cvSet2D( self, i, j, f )
96
+ end
97
+
98
+ def clone
99
+ CVFFI::cvCloneMat( self )
100
+ end
101
+
102
+ def mat_size
103
+ CVFFI::CvSize.new( :width => self.width, :height => self.height )
104
+ end
105
+
106
+ def twin
107
+ CVFFI::cvCreateMat( self.height, self.width, self.type )
108
+ end
109
+
110
+ def transpose
111
+ a = twin
112
+ CVFFI::cvTranspose( self, a )
113
+ a
114
+ end
115
+
116
+ def zero
117
+ CVFFI::cvSetZero( self )
118
+ end
119
+
120
+ def print( opts = {} )
121
+ CVFFI::print_matrix( self, opts )
122
+ end
123
+
124
+ module ClassMethods
125
+ def eye( x, type = :CV_32F )
126
+ a = CVFFI::cvCreateMat( x, x, type )
127
+ CVFFI::cvSetIdentity( a, CVFFI::CvScalar.new( :w => 1, :x => 1, :y => 1, :z => 1 ) )
128
+ a
129
+ end
130
+
131
+ def print( m, opts = {} )
132
+ CVFFI::print_matrix( m, opts )
133
+ end
134
+
135
+ end
136
+
137
+
138
+ end
139
+
140
+ class CvMat
141
+ include CvMatFunctions
142
+ end
143
+
144
+ class Mat
145
+ include CvMatFunctions
146
+
147
+ def self.wrap_function( s )
148
+ class_eval "def #{s}( *args ); Mat.new( mat.#{s}(*args) ); end"
149
+ end
150
+
151
+ def self.pass_function( s )
152
+ class_eval "def #{s}( *args ); mat.#{s}(*args); end"
153
+ end
154
+
155
+ [ :twin, :clone ].each { |f| wrap_function f }
156
+
157
+ attr_accessor :mat
158
+ attr_accessor :type
159
+
160
+ def initialize( *args )
161
+ a1,a2,a3 = *args
162
+ case a1
163
+ when Mat
164
+ # Copy constructor
165
+ @mat = a1.mat
166
+ when CvMat
167
+ @mat = a1
168
+ else
169
+ rows,cols,opts = a1,a2,a3
170
+ opts ||= {}
171
+ opts = { type: opts } if opts.is_a? Symbol
172
+ doZero = opts[:zero] || true
173
+ @type = opts[:type] || :CV_32F
174
+ @mat = CVFFI::cvCreateMat( rows, cols, @type )
175
+
176
+ mat.zero if doZero
177
+ end
178
+
179
+ if block_given?
180
+ rows.times { |i|
181
+ cols.times { |j|
182
+ set(i,j, yield(i,j) )
183
+ }
184
+ }
185
+ end
186
+
187
+ end
188
+
189
+ def at=(i,j,v)
190
+ if type == :CV_32F
191
+ mat.set_f( i,j, v)
192
+ else
193
+ mat.set_scalar( i,j, CVFFI::CvScalar.new( { w: v, x: v, y: v, z: v } ) )
194
+ end
195
+ end
196
+ alias :[]= :at=
197
+ alias :set :at=
198
+
199
+ def at(i,j)
200
+ if type == :CV_32F
201
+ mat.at_f( i,j)
202
+ else
203
+ s = mat.at_scalar( i,j )
204
+ s.w
205
+ end
206
+ end
207
+ alias :[] :at
208
+
209
+ def each( &blk )
210
+ each_with_indices { |v,i,j| blk.call( v ) }
211
+ end
212
+
213
+ def each_with_indices( &blk )
214
+ height.times { |i|
215
+ width.times { |j|
216
+ blk.call at(i,j), i, j
217
+ }
218
+ }
219
+ end
220
+
221
+
222
+ [ :height, :width ].each { |f| pass_function f }
223
+
224
+ def self.build( rows, cols, opts = {}, &blk )
225
+ Mat.new( rows, cols, opts ) { |i,j| blk.call(i,j) }
226
+ end
227
+
228
+ def self.eye( size, opts = {} )
229
+ m = Mat.new( size,size,opts )
230
+ size.times { |i| m[i,i] = 1 }
231
+ m
232
+ end
233
+
234
+ def self.rows( r, opts = {} )
235
+ height = r.length
236
+ width = r[0].length
237
+
238
+ Mat.build( height, width, opts ) { |i,j|
239
+ r[i][j]
240
+ }
241
+ end
242
+
243
+
244
+ # Should impedence match Mat anywhere a CvMat * is required...
245
+ # TODO: Figure out how to handler passing by_value
246
+ def to_ptr
247
+ @mat.pointer
248
+ end
249
+
250
+ def norm( b, type = :CV_L2 )
251
+ CVFFI::cvNorm( self, b, type )
252
+ end
253
+ def l2distance(b); norm(b, :CV_L2 ); end
254
+
255
+ def ==(b)
256
+ return false if width != b.width or height != b.height or type != b.type
257
+
258
+ cmpResult = Mat.new( height, width, :CV_8U )
259
+ # Fills cmpResults with 1 for each element which is not equal
260
+ CVFFI::cvCmp( self, b, cmpResult, :CV_CMP_NE )
261
+
262
+ # If results are equal, cmpResult will be all zeros
263
+ sum = CVFFI::cvSum( cmpResult )
264
+ sum.w == 0
265
+ end
266
+
267
+ end
268
+ end