ropencv 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d2e6aa5a66cdc073f75cbcef5ecdf2754dec1b9c
4
+ data.tar.gz: 78f996037687e4e836aee3f2ca2f540f79ece752
5
+ SHA512:
6
+ metadata.gz: b94532ed19232a2bd9a3758cfa13293f999fb94139b51c0b9ee5dbd742c07d82c06516c5465d4439c7d51bb920a82b791dccf9e0232bb5812d1e47b01fa32987
7
+ data.tar.gz: fd2e2023995003ccfbcd35edfc59c373d2f58dcd998828ab26ac7f21fe79d00f544167c87bb199390e774aad4a9279970ba96be9896f478e1e712e0d7fa93456
@@ -0,0 +1,22 @@
1
+ require 'ropencv'
2
+ include OpenCV
3
+
4
+ img = cv::imread("logo.png")
5
+ gray = cv::Mat.new
6
+ cv::cvtColor(img,gray,CV_BGR2GRAY)
7
+
8
+ circles = cv::Mat.new
9
+ cv::HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 1, gray.rows/10, 10, 20 );
10
+ circles = circles.reshape(1,circles.cols)
11
+
12
+ circles.each_row do |circle|
13
+ center = cv::Point.new(circle[0].round, circle[1].round)
14
+ radius = circle[2].round
15
+ # draw the circle center
16
+ cv::circle( img, center, 3, cv::Scalar.new(0,255,0),-1,8,0)
17
+ # draw the circle outline
18
+ cv::circle( img, center, radius, cv::Scalar.new(0,0,255),3, 8,0)
19
+ end
20
+
21
+ cv::imshow("Circles",img)
22
+ cv::wait_key(-1)
@@ -0,0 +1,33 @@
1
+ require 'ropencv'
2
+ include OpenCV
3
+
4
+ img1 = cv::imread('tsukuba_l.png',CV_LOAD_IMAGE_GRAYSCALE)
5
+ img2 = cv::imread('tsukuba_r.png',CV_LOAD_IMAGE_GRAYSCALE)
6
+ if (img1.empty() || img2.empty())
7
+ puts("Can't read one of the images\n")
8
+ return -1
9
+ end
10
+
11
+ keypoints1=Vector.new(cv::KeyPoint)
12
+ keypoints2=Vector.new(cv::KeyPoint)
13
+ detector = cv::FeatureDetector::create('SURF')
14
+ detector.detect(img1, keypoints1)
15
+ detector.detect(img2, keypoints2)
16
+
17
+ # computing descriptors
18
+ extractor=cv::DescriptorExtractor::create('SURF')
19
+ descriptors2=cv::Mat.new(3, 4, cv::CV_64FC1)
20
+ descriptors1=cv::Mat.new(3, 4, cv::CV_64FC1)
21
+ extractor.compute(img1, keypoints1, descriptors1)
22
+ extractor.compute(img2, keypoints2, descriptors2)
23
+
24
+ # matching descriptors
25
+ matcher= cv::BFMatcher::create('BruteForce-L1')
26
+ matches= Vector.new(cv::DMatch)
27
+ matcher.match(descriptors1, descriptors2, matches)
28
+
29
+ # drawing the results
30
+ img_matches=cv::Mat.new(3, 4, cv::CV_64FC1)
31
+ cv::drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches)
32
+ cv::imshow("matches", img_matches)
33
+ cv::waitKey(0)
Binary file
Binary file
data/ext/helper.rb CHANGED
@@ -27,6 +27,36 @@ class OpenCVPtr < Rbind::RTemplateClass
27
27
  end
28
28
  end
29
29
 
30
+ # Template for opencv's new smart pointer
31
+ class OpenCVPtr2 < Rbind::RTemplateClass
32
+ def initialize(name="cv::Ptr")
33
+ super
34
+ end
35
+
36
+ def specialize(klass,*parameters)
37
+ if parameters.size != 1
38
+ raise ArgumentError,"OpenCVPtr2 does only support one template parameter. Got: #{parameters}}"
39
+ end
40
+ ptr_type = parameters.first
41
+
42
+ klass.add_operation Rbind::ROperation.new(klass.name,nil,Rbind::RParameter.new("other",klass))
43
+ klass.add_operation Rbind::ROperation.new(klass.name,nil,Rbind::RParameter.new("p",ptr_type.to_ptr))
44
+ klass.add_operation Rbind::ROperation.new("release",type("void"))
45
+ klass.add_operation Rbind::ROperation.new("reset",type("void"),Rbind::RParameter.new("p",ptr_type.to_ptr))
46
+ klass.add_operation Rbind::ROperation.new("swap",type("void"),Rbind::RParameter.new("other",klass))
47
+ klass.add_operation Rbind::ROperation.new("get",ptr_type.to_ptr)
48
+ klass.add_operation Rbind::ROperation.new("empty",type("bool"))
49
+ klass
50
+ end
51
+
52
+ def specialize_ruby_specialization(klass)
53
+ " def method_missing(m,*args)\n"\
54
+ " raise \"Ptr #{self} is empty. Cannot call \#{m} on it!\" if empty\n"\
55
+ " get.method(m).call(*args)\n"\
56
+ " end\n"
57
+ end
58
+ end
59
+
30
60
  class Vec < Rbind::RClass
31
61
  def initialize(name,type,size)
32
62
  super(name)
data/ext/opencv.txt CHANGED
@@ -229,17 +229,17 @@ cv.Size.Size
229
229
  int height
230
230
  cv.Size.area int
231
231
  class cv.Size2f
232
- int width /RW
233
- int height /RW
232
+ float width /RW
233
+ float height /RW
234
234
  cv.Size2f.Size2f
235
235
  cv.Size2f.Size2f
236
236
  Size2f sz
237
237
  cv.Size2f.Size2f
238
238
  Point2f pt
239
239
  cv.Size2f.Size2f
240
- int width
241
- int height
242
- cv.Size2f.area int
240
+ float width
241
+ float height
242
+ cv.Size2f.area float
243
243
  cv.Rect.Rect
244
244
  cv.Rect.Rect
245
245
  Rect rect
data/ext/rbind.rb CHANGED
@@ -13,10 +13,11 @@ rbind.includes = opencv_headers
13
13
  rbind.parser.type_alias["const_c_string"] = rbind.c_string.to_const
14
14
  if opencv_version >= "2.4.9"
15
15
  rbind.add_std_types
16
+ rbind.parser.add_type OpenCVPtr2.new
16
17
  else
17
18
  rbind.add_std_vector
19
+ rbind.parser.add_type OpenCVPtr.new
18
20
  end
19
- rbind.parser.add_type OpenCVPtr.new
20
21
 
21
22
  # add Vec types
22
23
  2.upto(6) do |idx|
@@ -36,9 +37,15 @@ rbind.parse_headers
36
37
  rbind.parse File.join(File.dirname(__FILE__),"post_opencv244.txt")
37
38
 
38
39
  # post parsing + patching wrong signatures
39
- if opencv_version >= "2.4.9"
40
+ if opencv_version >= "2.4.9" && opencv_version < "3.0.0"
41
+ rbind.parse File.join(File.dirname(__FILE__),"post_opencv249.txt")
42
+ rbind.cv.randShuffle.parameter(2).remove_const!
43
+ elsif opencv_version >= "3.0.0"
40
44
  rbind.parse File.join(File.dirname(__FILE__),"post_opencv249.txt")
41
45
  rbind.cv.randShuffle.parameter(2).remove_const!
46
+ rbind.cv.AlignExposures.process.parameter(1).remove_const!
47
+ rbind.cv.AlignMTB.process[0].parameter(1).remove_const!
48
+ rbind.cv.AlignMTB.process[1].parameter(1).remove_const!
42
49
  end
43
50
 
44
51
  rbind.cv.CascadeClassifier.detectMultiScale[1].parameter(2).remove_const!
@@ -82,6 +89,14 @@ if ARGV.include?("--doc")
82
89
  end
83
90
  end
84
91
 
92
+ # replace default parameter values which are template
93
+ # functions and not available on the ruby side
94
+ Rbind::GeneratorRuby.on_normalize_default_value do |parameter|
95
+ if parameter.default_value =~ /.*makePtr<(.*)>\(\)/
96
+ "cv::Ptr<#{$1}>(new #{$1})"
97
+ end
98
+ end
99
+
85
100
  # generate files
86
101
  rbind.generator_ruby.file_prefix = "ropencv"
87
102
  rbind.generate(File.join(File.dirname(__FILE__),"src"),File.join(File.dirname(__FILE__),"..","lib","ropencv"))
@@ -1,9 +1,12 @@
1
1
  module OpenCV
2
2
  def self.included(obj)
3
- obj.class_eval do
3
+ obj.class_eval do
4
4
  def cv
5
5
  Cv
6
6
  end
7
+ def std
8
+ Std
9
+ end
7
10
  end
8
11
  end
9
12
 
@@ -68,6 +71,44 @@ module OpenCV
68
71
  end
69
72
  end
70
73
 
74
+ module Vec2x
75
+ def self.included base
76
+ base.instance_eval do
77
+ def to_native(obj,context)
78
+ if obj.is_a? ::OpenCV::Cv::Point
79
+ self.new(obj.x,obj.y).__obj_ptr__
80
+ elsif obj.is_a? ::OpenCV::Cv::Point2f
81
+ self.new(obj.x,obj.y).__obj_ptr__
82
+ elsif obj.is_a? ::OpenCV::Cv::Point2d
83
+ self.new(obj.x,obj.y).__obj_ptr__
84
+ elsif obj.is_a?(::OpenCV::Cv::Mat) && obj.rows == 2 && obj.cols == 1
85
+ self.new(obj[0],obj[1]).__obj_ptr__
86
+ else
87
+ rbind_to_native(obj,context)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ module Vec3x
95
+ def self.included base
96
+ base.instance_eval do
97
+ def to_native(obj,context)
98
+ if obj.is_a? ::OpenCV::Cv::Point3f
99
+ self.new(obj.x,obj.y,obj.z).__obj_ptr__
100
+ elsif obj.is_a? ::OpenCV::Cv::Point3d
101
+ self.new(obj.x,obj.y,obj.z).__obj_ptr__
102
+ elsif obj.is_a?(::OpenCV::Cv::Mat) && obj.rows == 3 && obj.cols == 1
103
+ self.new(obj[0],obj[1],obj[2]).__obj_ptr__
104
+ else
105
+ rbind_to_native(obj,context)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+
71
112
  module Vecxd
72
113
  def [](i)
73
114
  raise "Out of bound #{i}" if i < 0 || i >= self.class::SIZE
@@ -110,13 +151,13 @@ module OpenCV
110
151
  end
111
152
  end
112
153
 
113
- class Vec2d;include Vecxd; SIZE=2;end
114
- class Vec2f;include Vecxf; SIZE=2;end
115
- class Vec2i;include Vecxi; SIZE=2;end
154
+ class Vec2d;include Vecxd;include Vec2x; SIZE=2;end
155
+ class Vec2f;include Vecxf;include Vec2x; SIZE=2;end
156
+ class Vec2i;include Vecxi;include Vec2x; SIZE=2;end
116
157
 
117
- class Vec3d;include Vecxd; SIZE=3;end
118
- class Vec3f;include Vecxf; SIZE=3;end
119
- class Vec3i;include Vecxi; SIZE=3;end
158
+ class Vec3d;include Vecxd;include Vec3x; SIZE=3;end
159
+ class Vec3f;include Vecxf;include Vec3x; SIZE=3;end
160
+ class Vec3i;include Vecxi;include Vec3x; SIZE=3;end
120
161
 
121
162
  class Vec4d;include Vecxd; SIZE=4;end
122
163
  class Vec4f;include Vecxf; SIZE=4;end
@@ -160,7 +201,7 @@ module OpenCV
160
201
  elsif e.is_a? Float
161
202
  [:put_array_of_float64,8*w,CV_64FC1]
162
203
  else
163
- raise "cannot connvert arrays of #{e.class} to array"
204
+ raise ArgumentError,"cannot connvert array of #{e.class} to cv::Mat"
164
205
  end
165
206
  mat = Mat.new(h,w,type)
166
207
  ptr = mat.data
@@ -169,7 +210,7 @@ module OpenCV
169
210
  setter.call(0,obj)
170
211
  else
171
212
  obj.each_with_index do |row,i|
172
- raise "number of row elements must be equal for each row" if row.size != w
213
+ raise ArgumentError, "number of row elements must be equal for each row" if row.size != w
173
214
  setter.call(i*step,row)
174
215
  end
175
216
  end
@@ -340,6 +381,48 @@ module OpenCV
340
381
  pp.text str
341
382
  end
342
383
 
384
+ def each_row_with_index(&block)
385
+ if block_given?
386
+ r = rows
387
+ 0.upto(r-1) do |i|
388
+ yield(row(i),i)
389
+ end
390
+ else
391
+ to_enum(:each_row_with_index)
392
+ end
393
+ end
394
+
395
+ def each_col_with_index(&block)
396
+ if block_given?
397
+ c = cols
398
+ 0.upto(c-1) do |i|
399
+ yield(col(i),i)
400
+ end
401
+ else
402
+ to_enum(:each_col_with_index)
403
+ end
404
+ end
405
+
406
+ def each_row(&block)
407
+ if block_given?
408
+ each_row_with_index do |r,i|
409
+ yield(r)
410
+ end
411
+ else
412
+ to_enum(:each_row)
413
+ end
414
+ end
415
+
416
+ def each_col(&block)
417
+ if block_given?
418
+ each_col_with_index do |c,i|
419
+ yield(c)
420
+ end
421
+ else
422
+ to_enum(:each_col)
423
+ end
424
+ end
425
+
343
426
  def to_a
344
427
  h,w,c,s,ptr = [rows,cols,channels,step,data]
345
428
  getter = case type & 7
data/ropencv.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'ropencv'
3
- s.version = '0.0.11'
4
- s.date = '2013-08-21'
3
+ s.version = '0.0.12'
4
+ s.date = '2013-10-29'
5
5
  s.platform = Gem::Platform::RUBY
6
6
  s.authors = ['Alexander Duda']
7
7
  s.email = ['Alexander.Duda@dfki.de']
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.files = `git ls-files`.split("\n") + ["lib/ropencv/ropencv_types.rb","lib/ropencv/ropencv_ruby.rb"]
12
12
  s.require_path = 'lib'
13
13
  s.required_rubygems_version = ">= 1.3.6"
14
- s.add_runtime_dependency "rbind", "~> 0.0.21"
14
+ s.add_runtime_dependency "rbind", ">= 0.0.22"
15
15
  s.add_runtime_dependency "ffi", "~> 1.9.0"
16
16
  s.extensions = ['ext/extconf.rb']
17
17
  s.license = 'BSD'
data/test/suite.rb CHANGED
@@ -2,4 +2,5 @@ require './test_mat'
2
2
  require './test_vec'
3
3
  require './test_vector'
4
4
  require './test_scalar'
5
+ require './test_opencv'
5
6
  require './test_triangulate_points'
data/test/test_mat.rb CHANGED
@@ -49,6 +49,79 @@ describe Cv::Mat do
49
49
  end
50
50
  end
51
51
 
52
+ describe "each_row" do
53
+ it "iterators over each row" do
54
+ mat = cv::Mat.new([1,2,3],[3,3,3],[5,6,7])
55
+ result = []
56
+ mat.each_row do |r|
57
+ result << r
58
+ end
59
+ assert_equal [1,2,3], result[0].to_a.flatten!
60
+ assert_equal [3,3,3], result[1].to_a.flatten!
61
+ assert_equal [5,6,7], result[2].to_a.flatten!
62
+ end
63
+ it "returns an enumerator if no block is given" do
64
+ mat = cv::Mat.new([1,2,3],[3,3,3],[5,6,7])
65
+ result = mat.each_row.to_a
66
+ assert_equal [1,2,3], result[0].to_a.flatten!
67
+ assert_equal [3,3,3], result[1].to_a.flatten!
68
+ assert_equal [5,6,7], result[2].to_a.flatten!
69
+ end
70
+ end
71
+
72
+ describe "each_row_with_index" do
73
+ it "iterators over each row" do
74
+ mat = cv::Mat.new([1,2,3],[3,3,3],[5,6,7])
75
+ result = []
76
+ result_i = []
77
+ mat.each_row_with_index do |r,i|
78
+ result << r
79
+ result_i << i
80
+ end
81
+ assert_equal [1,2,3], result[0].to_a.flatten!
82
+ assert_equal [3,3,3], result[1].to_a.flatten!
83
+ assert_equal [5,6,7], result[2].to_a.flatten!
84
+ assert_equal [0,1,2], result_i
85
+ end
86
+ end
87
+
88
+ describe "each_col" do
89
+ it "iterators over each col" do
90
+ mat = cv::Mat.new([1,2,3],[3,3,3],[5,6,7])
91
+ result = []
92
+ mat.each_col do |r|
93
+ result << r
94
+ end
95
+ assert_equal [1,3,5], result[0].to_a.flatten!
96
+ assert_equal [2,3,6], result[1].to_a.flatten!
97
+ assert_equal [3,3,7], result[2].to_a.flatten!
98
+ end
99
+ it "returns an enumerator if no block is given" do
100
+ mat = cv::Mat.new([1,2,3],[3,3,3],[5,6,7])
101
+ result = mat.each_col.to_a
102
+ assert_equal [1,3,5], result[0].to_a.flatten!
103
+ assert_equal [2,3,6], result[1].to_a.flatten!
104
+ assert_equal [3,3,7], result[2].to_a.flatten!
105
+ end
106
+ end
107
+
108
+ describe "each_col_with_index" do
109
+ it "iterators over each col" do
110
+ mat = cv::Mat.new([1,2,3],[3,3,3],[5,6,7])
111
+ result = []
112
+ result_i = []
113
+ mat.each_col_with_index do |c,i|
114
+ result << c
115
+ result_i << i
116
+ end
117
+ assert_equal [1,3,5], result[0].to_a.flatten!
118
+ assert_equal [2,3,6], result[1].to_a.flatten!
119
+ assert_equal [3,3,7], result[2].to_a.flatten!
120
+ assert_equal [0,1,2], result_i
121
+ end
122
+ end
123
+
124
+
52
125
  describe "[]" do
53
126
  it "can return a specific value" do
54
127
  mat = cv::Mat.new([1,2,3],[3,3,3],[5,6,7])
@@ -0,0 +1,28 @@
1
+ require 'minitest/spec'
2
+ require 'ropencv'
3
+ require 'pp'
4
+ include OpenCV
5
+
6
+ MiniTest::Unit.autorun
7
+ describe OpenCV::Cv do
8
+ before do
9
+ end
10
+
11
+ after do
12
+ end
13
+
14
+ describe "perspectiveTransfrom" do
15
+ it "can be called from ruby" do
16
+ t = cv::Mat::eye(3,3, cv::CV_64FC1)
17
+ points = std::Vector.new(cv::Point2f)
18
+ 0.upto 10 do |i|
19
+ points << cv::Point2f.new(i,i)
20
+ end
21
+ mat = cv::Mat.new(points).reshape(2,points.size)
22
+ out = cv::Mat.new
23
+ cv::perspectiveTransform(mat,out,t)
24
+ assert_equal points.size, out.rows
25
+ end
26
+ end
27
+ end
28
+
metadata CHANGED
@@ -1,56 +1,63 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: ropencv
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.0.11
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.12
6
5
  platform: ruby
7
- authors:
6
+ authors:
8
7
  - Alexander Duda
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
-
13
- date: 2013-08-21 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
11
+ date: 2013-10-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
16
14
  name: rbind
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.22
20
+ type: :runtime
17
21
  prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
19
- none: false
20
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.22
27
+ - !ruby/object:Gem::Dependency
28
+ name: ffi
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
21
31
  - - ~>
22
- - !ruby/object:Gem::Version
23
- version: 0.0.21
32
+ - !ruby/object:Gem::Version
33
+ version: 1.9.0
24
34
  type: :runtime
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: ffi
28
35
  prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
30
- none: false
31
- requirements:
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
32
38
  - - ~>
33
- - !ruby/object:Gem::Version
39
+ - !ruby/object:Gem::Version
34
40
  version: 1.9.0
35
- type: :runtime
36
- version_requirements: *id002
37
- description: ROpenCV is a ffi ruby binding for the Open Source Computer Vision Library OpenCV 2.4.4 and higher
38
- email:
41
+ description: ROpenCV is a ffi ruby binding for the Open Source Computer Vision Library
42
+ OpenCV 2.4.4 and higher
43
+ email:
39
44
  - Alexander.Duda@dfki.de
40
45
  executables: []
41
-
42
- extensions:
46
+ extensions:
43
47
  - ext/extconf.rb
44
48
  extra_rdoc_files: []
45
-
46
- files:
49
+ files:
47
50
  - .gitignore
48
51
  - .yardopts
49
52
  - CMakeLists.txt
50
53
  - License.txt
51
54
  - README.md
52
55
  - examples/find_keypoints.rb
56
+ - examples/hough_circles.rb
53
57
  - examples/logo.png
58
+ - examples/match_keypoints.rb
59
+ - examples/tsukuba_l.png
60
+ - examples/tsukuba_r.png
54
61
  - ext/CMakeLists.txt
55
62
  - ext/extconf.rb
56
63
  - ext/helper.rb
@@ -71,38 +78,34 @@ files:
71
78
  - ropencv.gemspec
72
79
  - test/suite.rb
73
80
  - test/test_mat.rb
81
+ - test/test_opencv.rb
74
82
  - test/test_scalar.rb
75
83
  - test/test_triangulate_points.rb
76
84
  - test/test_vec.rb
77
85
  - test/test_vector.rb
78
86
  - lib/ropencv/ropencv_types.rb
79
87
  homepage: http://www.ropencv.aduda.eu
80
- licenses:
88
+ licenses:
81
89
  - BSD
90
+ metadata: {}
82
91
  post_install_message:
83
92
  rdoc_options: []
84
-
85
- require_paths:
93
+ require_paths:
86
94
  - lib
87
- required_ruby_version: !ruby/object:Gem::Requirement
88
- none: false
89
- requirements:
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- version: "0"
93
- required_rubygems_version: !ruby/object:Gem::Requirement
94
- none: false
95
- requirements:
96
- - - ">="
97
- - !ruby/object:Gem::Version
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
98
104
  version: 1.3.6
99
105
  requirements: []
100
-
101
106
  rubyforge_project:
102
- rubygems_version: 1.8.23
107
+ rubygems_version: 2.0.3
103
108
  signing_key:
104
- specification_version: 3
109
+ specification_version: 4
105
110
  summary: Ruby bindings for opencv 2.4.4 and higher
106
111
  test_files: []
107
-
108
- has_rdoc: