opencv-ffi 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +15 -0
- data/README.md +126 -0
- data/Rakefile +52 -0
- data/docs/DocsIndex.md +1 -0
- data/docs/examples/load_image.rb +25 -0
- data/ext/Rakefile +13 -0
- data/ext/aishack-sift/.gitignore +4 -0
- data/ext/aishack-sift/Descriptor.h +34 -0
- data/ext/aishack-sift/KeyPoint.h +38 -0
- data/ext/aishack-sift/README +20 -0
- data/ext/aishack-sift/SIFT.cpp +1036 -0
- data/ext/aishack-sift/SIFT.h +84 -0
- data/ext/aishack-sift/example/.gitignore +2 -0
- data/ext/aishack-sift/example/Makefile +24 -0
- data/ext/aishack-sift/example/MySIFT.cpp +29 -0
- data/ext/aishack-sift/mkrf_conf.rb +13 -0
- data/ext/aishack-sift/siftlib.cpp +85 -0
- data/ext/eigen/.gitignore +4 -0
- data/ext/eigen/eigen_polynomial.cpp +41 -0
- data/ext/eigen/eigen_svd.cpp +100 -0
- data/ext/eigen/mkrf_conf.rb +14 -0
- data/ext/mkrf-monkey.rb +85 -0
- data/ext/mkrf-rakehelper-monkey.rb +52 -0
- data/ext/mkrf_conf.rb +3 -0
- data/ext/opencv-ffi/.gitignore +4 -0
- data/ext/opencv-ffi/matcher_helper.cpp +56 -0
- data/ext/opencv-ffi/mkrf_conf.rb +12 -0
- data/ext/opencv-ffi/vector_math.cpp +39 -0
- data/ext/opensurf/.gitignore +4 -0
- data/ext/opensurf/README +38 -0
- data/ext/opensurf/fasthessian.cpp +376 -0
- data/ext/opensurf/fasthessian.h +108 -0
- data/ext/opensurf/integral.cpp +58 -0
- data/ext/opensurf/integral.h +55 -0
- data/ext/opensurf/ipoint.cpp +108 -0
- data/ext/opensurf/ipoint.h +76 -0
- data/ext/opensurf/kmeans.h +172 -0
- data/ext/opensurf/mkrf_conf.rb +10 -0
- data/ext/opensurf/responselayer.h +92 -0
- data/ext/opensurf/surf.cpp +317 -0
- data/ext/opensurf/surf.h +66 -0
- data/ext/opensurf/surflib.cpp +98 -0
- data/ext/opensurf/surflib.h +96 -0
- data/ext/opensurf/utils.cpp +357 -0
- data/ext/opensurf/utils.h +63 -0
- data/lib/.gitignore +1 -0
- data/lib/opencv-ffi-ext/eigen.rb +84 -0
- data/lib/opencv-ffi-ext/features2d.rb +4 -0
- data/lib/opencv-ffi-ext/matcher_helper.rb +24 -0
- data/lib/opencv-ffi-ext/opensurf.rb +217 -0
- data/lib/opencv-ffi-ext/sift.rb +118 -0
- data/lib/opencv-ffi-ext/vector_math.rb +115 -0
- data/lib/opencv-ffi-wrappers.rb +7 -0
- data/lib/opencv-ffi-wrappers/core.rb +24 -0
- data/lib/opencv-ffi-wrappers/core/iplimage.rb +50 -0
- data/lib/opencv-ffi-wrappers/core/mat.rb +268 -0
- data/lib/opencv-ffi-wrappers/core/misc_draw.rb +44 -0
- data/lib/opencv-ffi-wrappers/core/point.rb +286 -0
- data/lib/opencv-ffi-wrappers/core/rect.rb +40 -0
- data/lib/opencv-ffi-wrappers/core/scalar.rb +104 -0
- data/lib/opencv-ffi-wrappers/core/size.rb +88 -0
- data/lib/opencv-ffi-wrappers/enumerable.rb +10 -0
- data/lib/opencv-ffi-wrappers/features2d.rb +17 -0
- data/lib/opencv-ffi-wrappers/features2d/image_patch.rb +322 -0
- data/lib/opencv-ffi-wrappers/features2d/star.rb +111 -0
- data/lib/opencv-ffi-wrappers/features2d/surf.rb +115 -0
- data/lib/opencv-ffi-wrappers/highgui.rb +10 -0
- data/lib/opencv-ffi-wrappers/imgproc.rb +4 -0
- data/lib/opencv-ffi-wrappers/imgproc/features.rb +35 -0
- data/lib/opencv-ffi-wrappers/imgproc/geometric.rb +39 -0
- data/lib/opencv-ffi-wrappers/matcher.rb +297 -0
- data/lib/opencv-ffi-wrappers/matrix.rb +37 -0
- data/lib/opencv-ffi-wrappers/misc.rb +41 -0
- data/lib/opencv-ffi-wrappers/misc/params.rb +34 -0
- data/lib/opencv-ffi-wrappers/sequence.rb +37 -0
- data/lib/opencv-ffi-wrappers/vectors.rb +38 -0
- data/lib/opencv-ffi.rb +12 -0
- data/lib/opencv-ffi/calib3d.rb +26 -0
- data/lib/opencv-ffi/core.rb +15 -0
- data/lib/opencv-ffi/core/draw.rb +68 -0
- data/lib/opencv-ffi/core/dynamic.rb +13 -0
- data/lib/opencv-ffi/core/library.rb +5 -0
- data/lib/opencv-ffi/core/operations.rb +122 -0
- data/lib/opencv-ffi/core/point.rb +22 -0
- data/lib/opencv-ffi/core/types.rb +172 -0
- data/lib/opencv-ffi/cvffi.rb +8 -0
- data/lib/opencv-ffi/features2d.rb +7 -0
- data/lib/opencv-ffi/features2d/library.rb +6 -0
- data/lib/opencv-ffi/features2d/star.rb +30 -0
- data/lib/opencv-ffi/features2d/surf.rb +38 -0
- data/lib/opencv-ffi/highgui.rb +31 -0
- data/lib/opencv-ffi/imgproc.rb +9 -0
- data/lib/opencv-ffi/imgproc/features.rb +37 -0
- data/lib/opencv-ffi/imgproc/geometric.rb +42 -0
- data/lib/opencv-ffi/imgproc/library.rb +6 -0
- data/lib/opencv-ffi/imgproc/misc.rb +39 -0
- data/lib/opencv-ffi/version.rb +3 -0
- data/opencv-ffi.gemspec +26 -0
- data/test/core/test_draw.rb +46 -0
- data/test/core/test_operations.rb +135 -0
- data/test/core/test_size.rb +14 -0
- data/test/core/test_text.rb +52 -0
- data/test/ext/test_eigen.rb +105 -0
- data/test/ext/test_opensurf.rb +35 -0
- data/test/ext/test_sift.rb +26 -0
- data/test/ext/test_vector_math.rb +85 -0
- data/test/features2d/test_surf.rb +63 -0
- data/test/imgproc/test_goodfeatures.rb +18 -0
- data/test/setup.rb +65 -0
- data/test/test_calib3d.rb +38 -0
- data/test/test_core.rb +26 -0
- data/test/test_ext.rb +8 -0
- data/test/test_features2d.rb +9 -0
- data/test/test_files/images/IMG_7088.JPG +0 -0
- data/test/test_files/images/IMG_7088_small.JPG +0 -0
- data/test/test_files/images/IMG_7089.JPG +0 -0
- data/test/test_highgui.rb +26 -0
- data/test/test_imgproc.rb +35 -0
- data/test/test_wrappers.rb +8 -0
- data/test/wrappers/core/test_draw.rb +41 -0
- data/test/wrappers/core/test_mat.rb +40 -0
- data/test/wrappers/core/test_operations.rb +35 -0
- data/test/wrappers/core/test_types.rb +235 -0
- data/test/wrappers/features2d/test_image_patch.rb +108 -0
- data/test/wrappers/test_imgproc.rb +87 -0
- data/test/wrappers/test_matcher.rb +96 -0
- data/test/wrappers/test_star.rb +28 -0
- data/test/wrappers/test_surf.rb +36 -0
- 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
|
data/lib/.gitignore
ADDED
@@ -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,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
|