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,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