1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00

Merge branch 'develop' into documentation

Conflicts:
	.gitignore
	ext/opencv/cvmat.cpp
	ext/opencv/opencv.cpp
This commit is contained in:
ser1zw 2014-01-14 17:45:45 +09:00
commit c88feb2c8e
105 changed files with 21911 additions and 347 deletions

3
.gitignore vendored
View file

@ -23,3 +23,6 @@ examples/contours/rotated-boxes-with-detected-bounding-rectangles.jpg
Gemfile.lock
.yardoc
.RUBYLIBDIR.*
.RUBYARCHDIR.*
.bundle

View file

@ -14,12 +14,11 @@
* [hoe](https://github.com/seattlerb/hoe)
* [hoe-gemspec](https://github.com/flavorjones/hoe-gemspec)
* [rake-compiler](https://github.com/luislavena/rake-compiler)
* [gem-compile](https://github.com/frsyuki/gem-compile)
## Create ruby-opencv gem
Run the following commands.
When you use mingw32, use **MSYS console**, or when you use mswin32,
When you use mingw32, use **MSYS console**, or when you use mswin32,
use [**Visual Studio Command Prompt**](http://msdn.microsoft.com/en-us/library/ms229859.aspx)
instead of cmd.exe.
@ -32,16 +31,34 @@ $ git ls-files > Manifest.txt
$ rake gem:spec
$ rake gem
```
**ruby-opencv-x.y.z.gem** will be created in pkg/ directory.
**ruby-opencv-x.y.z.gem** will be created in **pkg** directory.
To create pre-build binaries, run the following commands in Windows.
To create pre-build binaries, create a config file firstly:
```
$ cd pkg
$ gem compile ruby-opencv-*.gem
```yml
# config.yml
platform: mingw32
rubies:
- C:/ruby-1.9.3-p392-mingw32/bin/ruby.exe
- C:/ruby-2.0.0-p0-mingw32/bin/ruby.exe
extopts:
- --with-opencv-include=C:/opencv/build/include
- --with-opencv-lib=C:/opencv/build/x86/mingw/lib
```
**ruby-opencv-x.y.z-x86-mingw32.gem** will be created when you use mingw32, or
Entries are below:
- **platform**: Target platform (e.g. mingw32, mswin32)
- **rubies**: Array of target versions of ruby's paths (You can create fat gems if you specify multiple versions of ruby)
- **extopts**: Array of options to be passed to **extconf.rb**
Then, run the following command:
```
$ rake gem:precompile CONFIG=config.yml
```
**ruby-opencv-x.y.z-mingw32.gem** will be created when you use mingw32, or
**ruby-opencv-x.y.z-x86-mswin32.gem** when you use mswin32.
@ -52,7 +69,7 @@ $ gem compile ruby-opencv-*.gem
$ git clone git://github.com/ruby-opencv/ruby-opencv.git
$ cd ruby-opencv
$ git checkout master
$ ruby extconf.rb --with-opencv-dir=/path/to/opencvdir
$ ruby ext/opencv/extconf.rb --with-opencv-dir=/path/to/opencvdir
$ make
$ make install
```
@ -68,7 +85,7 @@ Run the following commands on [**Visual Studio Command Prompt**](http://msdn.mic
$ git clone git://github.com/ruby-opencv/ruby-opencv.git
$ cd ruby-opencv
$ git checkout master
$ ruby extconf.rb --with-opencv-dir=C:\path\to\opencvdir\install # for your own built OpenCV library
$ ruby ext/opencv/extconf.rb --with-opencv-dir=C:\path\to\opencvdir\install # for your own built OpenCV library
$ nmake
$ nmake install
```
@ -76,7 +93,7 @@ $ nmake install
To use pre-built OpenCV libraries, set the following option to extconf.rb.
```
$ ruby extconf.rb --with-opencv-include=C:\path\to\opencvdir\build\include --with-opencv-lib=C:\path\to\opencvdir\build\x86\vc10\lib
$ ruby ext/opencv/extconf.rb --with-opencv-include=C:\path\to\opencvdir\build\include --with-opencv-lib=C:\path\to\opencvdir\build\x86\vc10\lib
```
@ -88,7 +105,7 @@ Run the following commands on **MSYS console**.
$ git clone git://github.com/ruby-opencv/ruby-opencv.git
$ cd ruby-opencv
$ git checkout master
$ ruby extconf.rb --with-opencv-dir=/C/path/to/opencvdir/install # for your own built OpenCV library
$ ruby ext/opencv/extconf.rb --with-opencv-dir=/C/path/to/opencvdir/install # for your own built OpenCV library
$ make
$ make install
```
@ -96,7 +113,7 @@ $ make install
To use pre-built OpenCV libraries, set the following option to extconf.rb.
```
$ ruby extconf.rb --with-opencv-include=/c/path/to/opencvdir/build/include --with-opencv-lib=/c/path/to/opencvdir/build/x86/mingw/lib
$ ruby ext/opencv/extconf.rb --with-opencv-include=/c/path/to/opencvdir/build/include --with-opencv-lib=/c/path/to/opencvdir/build/x86/mingw/lib
```

View file

@ -1,9 +1,8 @@
source :gemcutter
source 'https://rubygems.org'
group :development do
gem "hoe"
gem "hoe-gemspec"
gem "rake-compiler"
gem "gem-compile"
end

View file

@ -1,4 +1,4 @@
The BSD Liscense
The BSD License
Copyright (c) 2008, Masakazu Yonekura
All rights reserved.

View file

@ -6,9 +6,8 @@ License.txt
Manifest.txt
README.md
Rakefile
config.yml
examples/alpha_blend.rb
examples/box.png
examples/box_in_scene.png
examples/contours/bitmap-contours-with-labels.png
examples/contours/bitmap-contours.png
examples/contours/bounding-box-detect-canny.rb
@ -16,14 +15,26 @@ examples/contours/contour_retrieval_modes.rb
examples/contours/rotated-boxes.jpg
examples/convexhull.rb
examples/face_detect.rb
examples/facerec/create_csv.rb
examples/facerec/facerec_eigenfaces.rb
examples/facerec/facerec_fisherfaces.rb
examples/facerec/facerec_lbph.rb
examples/facerec/readme.md
examples/find_obj.rb
examples/houghcircle.rb
examples/inpaint.png
examples/images/box.png
examples/images/box_in_scene.png
examples/images/inpaint.png
examples/images/lena-256x256.jpg
examples/images/lena-eyes.jpg
examples/images/lenna-rotated.jpg
examples/images/lenna.jpg
examples/images/stuff.jpg
examples/images/tiffany.jpg
examples/inpaint.rb
examples/lenna-rotated.jpg
examples/lenna.jpg
examples/match_kdtree.rb
examples/matching_to_many_images.rb
examples/match_template.rb
examples/matching_to_many_images/matching_to_many_images.rb
examples/matching_to_many_images/query.png
examples/matching_to_many_images/train/1.png
examples/matching_to_many_images/train/2.png
@ -31,8 +42,8 @@ examples/matching_to_many_images/train/3.png
examples/matching_to_many_images/train/trainImages.txt
examples/paint.rb
examples/snake.rb
examples/stuff.jpg
examples/tiffany.jpg
ext/opencv/algorithm.cpp
ext/opencv/algorithm.h
ext/opencv/curve.cpp
ext/opencv/curve.h
ext/opencv/cvavgcomp.cpp
@ -109,15 +120,21 @@ ext/opencv/cvutils.cpp
ext/opencv/cvutils.h
ext/opencv/cvvideowriter.cpp
ext/opencv/cvvideowriter.h
ext/opencv/eigenfaces.cpp
ext/opencv/eigenfaces.h
ext/opencv/extconf.rb
ext/opencv/facerecognizer.cpp
ext/opencv/facerecognizer.h
ext/opencv/fisherfaces.cpp
ext/opencv/fisherfaces.h
ext/opencv/gui.cpp
ext/opencv/gui.h
ext/opencv/iplconvkernel.cpp
ext/opencv/iplconvkernel.h
ext/opencv/iplimage.cpp
ext/opencv/iplimage.h
ext/opencv/lib/opencv.rb
ext/opencv/lib/opencv/psyched_yaml.rb
ext/opencv/lib/opencv/version.rb
ext/opencv/lbph.cpp
ext/opencv/lbph.h
ext/opencv/mouseevent.cpp
ext/opencv/mouseevent.h
ext/opencv/opencv.cpp
@ -128,13 +145,17 @@ ext/opencv/trackbar.cpp
ext/opencv/trackbar.h
ext/opencv/window.cpp
ext/opencv/window.h
extconf.rb
images/CvMat_sobel.png
images/CvMat_sub_rect.png
images/CvSeq_relationmap.png
images/face_detect_from_lena.jpg
lib/opencv.rb
lib/opencv/psyched_yaml.rb
lib/opencv/version.rb
ruby-opencv.gemspec
test/eigenfaces_save.xml
test/fisherfaces_save.xml
test/helper.rb
test/lbph_save.xml
test/runner.rb
test/samples/airplane.jpg
test/samples/baboon.jpg
@ -216,11 +237,15 @@ test/test_cvsurfpoint.rb
test/test_cvtermcriteria.rb
test/test_cvtwopoints.rb
test/test_cvvideowriter.rb
test/test_eigenfaces.rb
test/test_fisherfaces.rb
test/test_iplconvkernel.rb
test/test_iplimage.rb
test/test_lbph.rb
test/test_mouseevent.rb
test/test_opencv.rb
test/test_pointset.rb
test/test_preliminary.rb
test/test_trackbar.rb
test/test_window.rb
yard_extension.rb

View file

@ -3,7 +3,7 @@
An OpenCV wrapper for Ruby.
* Web site: <https://github.com/ruby-opencv/ruby-opencv>
* Ruby 1.8.7, 1.9.3 and OpenCV 2.4.3 are supported.
* Ruby 1.9.3, 2.0.0, 2.1.0 and OpenCV 2.4.8 are supported.
## Requirement

View file

@ -1,27 +1,36 @@
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'rubygems'
require './ext/opencv/lib/opencv/psyched_yaml'
require "rubygems/ext"
require "rubygems/installer"
require 'hoe'
require 'rake/extensiontask'
require 'fileutils'
require './lib/opencv/psyched_yaml'
SO_FILE = 'opencv.so'
Hoe.plugin :gemspec
hoespec = Hoe.spec 'ruby-opencv' do |s|
s.summary = 'OpenCV wrapper for Ruby'
s.description = 'ruby-opencv is a wrapper of OpenCV for Ruby. It helps you to write computer vision programs (e.g. detecting faces from pictures) with Ruby.'
s.licenses = ['The BSD License']
s.developer('lsxi', 'masakazu.yonekura@gmail.com')
s.developer('ser1zw', 'azariahsawtikes@gmail.com')
s.developer('pcting', 'pcting@gmail.com')
s.readme_file = 'README.md'
s.history_file = 'History.txt'
s.spec_extras = { :extensions => ['extconf.rb'] }
s.spec_extras = { :extensions => ['ext/opencv/extconf.rb'] }
s.test_globs = ['test/test_*.rb']
s.urls = ['https://github.com/ruby-opencv/ruby-opencv/']
s.extra_dev_deps << ['rake-compiler', '>= 0'] << ['hoe-gemspec']
Rake::ExtensionTask.new('opencv', spec) do |ext|
ext.lib_dir = File.join('lib', 'opencv')
ext.lib_dir = 'lib'
end
end
@ -29,4 +38,53 @@ hoespec.spec.files.delete('.gemtest')
Rake::Task[:test].prerequisites << :compile
desc 'Create a pre-compiled gem'
task 'gem:precompile' => ['gem'] do
tmp_dir = Dir.mktmpdir('tmp', '.')
gemfile = Dir.glob("pkg/*.gem")[0]
target_dir = File.join(tmp_dir, File.basename(gemfile, '.gem'))
installer = Gem::Installer.new(gemfile)
installer.unpack(target_dir)
gemspec = installer.spec
extension = gemspec.extensions[0]
gemspec.extensions.clear
config = ENV['CONFIG'] ? YAML.load_file(ENV['CONFIG']) : {}
rubies = config['rubies'] || [Gem.ruby]
args = config['extopts'] || []
gemspec.platform = config['platform'] || Gem::Platform::CURRENT
multi = rubies.size > 1
rubies.each { |ruby|
lib_dir = 'lib'
if multi
major, minor, _ = `#{ruby} -e "print RUBY_VERSION"`.chomp.split('.')
lib_dir = File.join(lib_dir, [major, minor].join('.'))
end
make_cmd = (`#{ruby} -e "print RUBY_PLATFORM"` =~ /mswin/) ? 'nmake' : 'make'
Dir.chdir(target_dir) {
cmd = [ruby, extension, *args].join(' ')
results = []
Gem::Ext::ExtConfBuilder.run(cmd, results)
Gem::Ext::ExtConfBuilder.make('', results)
FileUtils.mkdir_p lib_dir
FileUtils.mv SO_FILE, lib_dir
sh "#{make_cmd} clean"
}
gemspec.files << File.join(lib_dir, SO_FILE)
}
Dir.chdir(target_dir) {
gemfile = Gem::Package.build(gemspec)
FileUtils.mv gemfile, File.dirname(__FILE__)
}
FileUtils.rm_rf tmp_dir
end
# vim: syntax=ruby

7
config.yml Normal file
View file

@ -0,0 +1,7 @@
platform: mingw32
rubies:
- C:/ruby-1.9.3-p392-mingw32/bin/ruby.exe
- C:/ruby-2.0.0-p0-mingw32/bin/ruby.exe
extopts:
- --with-opencv-include=C:/opencv/build/include
- --with-opencv-lib=C:/opencv/build/x86/mingw/lib

View file

@ -1,13 +1,13 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
# Alpha blending sample with GUI
require 'opencv'
include OpenCV
img1 = IplImage.load('lenna.jpg', CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH)
img2 = IplImage.load('tiffany.jpg', CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH)
img1 = IplImage.load('images/lenna.jpg', CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH)
img2 = IplImage.load('images/tiffany.jpg', CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH)
window = GUI::Window.new('Alpha blend')
max = 100.0

43
examples/facerec/create_csv.rb Executable file
View file

@ -0,0 +1,43 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8 -*-
# This is a tiny script to help you creating a CSV file from a face
# database with a similar hierarchie:
#
# philipp@mango:~/facerec/data/at$ tree
# .
# |-- README
# |-- s1
# | |-- 1.pgm
# | |-- ...
# | |-- 10.pgm
# |-- s2
# | |-- 1.pgm
# | |-- ...
# | |-- 10.pgm
# ...
# |-- s40
# | |-- 1.pgm
# | |-- ...
# | |-- 10.pgm
#
# See http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html
#
if ARGV.size != 1
puts "usage: ruby #{__FILE__} <base_path>"
exit
end
BASE_PATH = ARGV[0]
SEPARATOR = ';'
label = 0
Dir.glob("#{BASE_PATH}/*").each { |dir|
if FileTest::directory? dir
Dir.glob("#{dir}/*") { |filename|
puts "#{filename}#{SEPARATOR}#{label}"
}
label += 1
end
}

View file

@ -0,0 +1,132 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8 -*-
# Eigenfaces sample in ruby-opencv, equivalent to http://docs.opencv.org/trunk/_downloads/facerec_eigenfaces.cpp
# See http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html
require 'opencv'
include OpenCV
def norm_0_255(src)
dst = nil
case src.channel
when 1
dst = src.normalize(0, 255, CV_NORM_MINMAX, CV_8UC1)
when 2
dst = src.normalize(0, 255, CV_NORM_MINMAX, CV_8UC3)
else
dst = src.copy
end
dst
end
def read_csv(filename, sepalator = ';')
images = []
labels = []
open(filename, 'r') { |f|
f.each { |line|
path, label = line.chomp.split(sepalator)
images << CvMat.load(path, CV_LOAD_IMAGE_GRAYSCALE)
labels << label.to_i
}
}
[images, labels]
end
if ARGV.size < 1
puts "usage: ruby #{__FILE__} <csv.ext> <output_folder>"
exit 1
end
fn_csv = ARGV.shift
output_folder = ARGV.shift
images, labels = read_csv(fn_csv);
height = images[0].rows;
# The following lines simply get the last images from your dataset and remove it
# from the vector. This is done, so that the training data (which we learn the
# cv::FaceRecognizer on) and the test data we test the model with, do not overlap.
test_sample = images.pop
test_label = labels.pop
# The following lines create an Eigenfaces model for
# face recognition and train it with the images and
# labels read from the given CSV file.
# This here is a full PCA, if you just want to keep
# 10 principal components (read Eigenfaces), then call
# the factory method like this:
#
# EigenFaces.new(10)
#
# If you want to create a FaceRecognizer with a
# confidence threshold (e.g. 123.0), call it with:
#
# EigenFaces.new(10, 123.0)
#
# If you want to use _all_ Eigenfaces and have a threshold,
# then call the method like this:
#
# EigenFaces.new(0, 123.0)
#
model = EigenFaces.new
model.train(images, labels)
# The following line predicts the label of a given test image:
predicted_label, predicted_confidence = model.predict(test_sample)
puts "Predicted class: #{predicted_label} / Actual class: #{test_label}"
eigenvalues = model.get_mat('eigenvalues')
w = model.get_mat('eigenvectors');
mean = model.get_mat('mean')
if output_folder
norm_0_255(mean.reshape(1, images[0].rows)).save("#{output_folder}/mean.png")
else
w1 = GUI::Window.new('Predicted')
w2 = GUI::Window.new('Actual')
w3 = GUI::Window.new('mean')
w1.show images[predicted_label]
w2.show images[test_label]
w3.show norm_0_255(mean.reshape(1, images[0].rows))
end
# Display or save the Eigenfaces:
[w.cols, 10].min.times { |i|
puts "Eigenvalue ##{i} = #{eigenvalues[i][0]}"
ev = w.get_cols(i).clone()
grayscale = norm_0_255(ev.reshape(1, height))
# Show the image & apply a Jet colormap for better sensing.
cgrayscale = grayscale.apply_color_map(COLORMAP_JET)
if output_folder
norm_0_255(cgrayscale).save("#{output_folder}/eigenface_#{i}.png")
else
w4 = GUI::Window.new("eigenface_#{i}")
w4.show norm_0_255(cgrayscale)
end
}
[w.cols, 10].min.step([w.cols, 300].min, 15) { |num_components|
# slice the eigenvectors from the model
evs = w.get_cols(0..num_components)
projection = images[0].reshape(1, 1).subspace_project(evs, mean)
reconstruction = projection.subspace_reconstruct(evs, mean)
# Normalize the result:
reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows))
# Display or save:
if output_folder
norm_0_255(reconstruction).save("#{output_folder}/eigenface_reconstruction_#{num_components}.png")
else
w5 = GUI::Window.new("eigenface_reconstruction_#{num_components}")
w5.show norm_0_255(reconstruction)
end
}
GUI::wait_key unless output_folder

View file

@ -0,0 +1,131 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8 -*-
# Fisherfaces sample in ruby-opencv, equivalent to http://docs.opencv.org/trunk/_downloads/facerec_fisherfaces.cpp
# See http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html
require 'opencv'
include OpenCV
def norm_0_255(src)
dst = nil
case src.channel
when 1
dst = src.normalize(0, 255, CV_NORM_MINMAX, CV_8UC1)
when 2
dst = src.normalize(0, 255, CV_NORM_MINMAX, CV_8UC3)
else
dst = src.copy
end
dst
end
def read_csv(filename, sepalator = ';')
images = []
labels = []
open(filename, 'r') { |f|
f.each { |line|
path, label = line.chomp.split(sepalator)
images << CvMat.load(path, CV_LOAD_IMAGE_GRAYSCALE)
labels << label.to_i
}
}
[images, labels]
end
if ARGV.size < 1
puts "usage: ruby #{__FILE__} <csv.ext> <output_folder>"
exit 1
end
fn_csv = ARGV.shift
output_folder = ARGV.shift
images, labels = read_csv(fn_csv);
height = images[0].rows;
# The following lines simply get the last images from your dataset and remove it
# from the vector. This is done, so that the training data (which we learn the
# cv::FaceRecognizer on) and the test data we test the model with, do not overlap.
test_sample = images.pop
test_label = labels.pop
# The following lines create an Fisherfaces model for
# face recognition and train it with the images and
# labels read from the given CSV file.
# If you just want to keep 10 Fisherfaces, then call
# the factory method like this:
#
# FisherFaces.new(10)
#
# However it is not useful to discard Fisherfaces! Please
# always try to use _all_ available Fisherfaces for
# classification.
#
# If you want to create a FaceRecognizer with a
# confidence threshold (e.g. 123.0) and use _all_
# Fisherfaces, then call it with:
#
# FisherFaces.new(0, 123.0);
#
model = FisherFaces.new
model.train(images, labels)
# The following line predicts the label of a given test image:
predicted_label, predicted_confidence = model.predict(test_sample)
puts "Predicted class: #{predicted_label} / Actual class: #{test_label}"
eigenvalues = model.get_mat('eigenvalues')
w = model.get_mat('eigenvectors');
mean = model.get_mat('mean')
if output_folder
norm_0_255(mean.reshape(1, images[0].rows)).save("#{output_folder}/mean.png")
else
w1 = GUI::Window.new('Predicted')
w2 = GUI::Window.new('Actual')
w3 = GUI::Window.new('mean')
w1.show images[predicted_label]
w2.show images[test_label]
w3.show norm_0_255(mean.reshape(1, images[0].rows))
end
# Display or save the first, at most 16 Fisherfaces
[w.cols, 16].min.times { |i|
puts "Eigenvalue ##{i} = #{eigenvalues[i][0]}"
ev = w.get_cols(i).clone()
grayscale = norm_0_255(ev.reshape(1, height))
# Show the image & apply a Bone colormap for better sensing.
cgrayscale = grayscale.apply_color_map(COLORMAP_BONE)
if output_folder
norm_0_255(cgrayscale).save("#{output_folder}/fisherface_#{i}.png")
else
w4 = GUI::Window.new("fisherface_#{i}")
w4.show norm_0_255(cgrayscale)
end
}
[w.cols, 16].min.times { |num_component|
# Slice the Fisherface from the model
ev = w.get_cols(num_component)
projection = images[0].reshape(1, 1).subspace_project(ev, mean)
reconstruction = projection.subspace_reconstruct(ev, mean)
# Normalize the result:
reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows))
# Display or save:
if output_folder
norm_0_255(reconstruction).save("#{output_folder}/fisherface_reconstruction_#{num_component}.png")
else
w5 = GUI::Window.new("fisherface_reconstruction_#{num_component}")
w5.show norm_0_255(reconstruction)
end
}
GUI::wait_key unless output_folder

116
examples/facerec/facerec_lbph.rb Executable file
View file

@ -0,0 +1,116 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8 -*-
# LBPH sample in ruby-opencv, equivalent to http://docs.opencv.org/trunk/_downloads/facerec_lbph.cpp
# See http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html
require 'opencv'
include OpenCV
def read_csv(filename, sepalator = ';')
images = []
labels = []
open(filename, 'r') { |f|
f.each { |line|
path, label = line.chomp.split(sepalator)
images << CvMat.load(path, CV_LOAD_IMAGE_GRAYSCALE)
labels << label.to_i
}
}
[images, labels]
end
# Check for valid command line arguments, print usage
# if no arguments were given.
if ARGV.size < 1
puts "usage: ruby #{__FILE__} <csv.ext>"
exit 1
end
# Get the path to your CSV.
fn_csv = ARGV.shift
# Read in the data. This can fail if no valid
# input filename is given.
images, labels = read_csv(fn_csv);
# Quit if there are not enough images for this demo.
raise 'This demo needs at least 2 images to work. Please add more images to your data set!' if images.size <= 1
# Get the height from the first image. We'll need this
# later in code to reshape the images to their original size:
height = images[0].rows;
# The following lines simply get the last images from
# your dataset and remove it from the vector. This is
# done, so that the training data (which we learn the
# cv::FaceRecognizer on) and the test data we test
# the model with, do not overlap.
test_sample = images.pop
test_label = labels.pop
# The following lines create an LBPH model for
# face recognition and train it with the images and
# labels read from the given CSV file.
#
# The LBPHFaceRecognizer uses Extended Local Binary Patterns
# (it's probably configurable with other operators at a later
# point), and has the following default values
#
# radius = 1
# neighbors = 8
# grid_x = 8
# grid_y = 8
#
# So if you want a LBPH FaceRecognizer using a radius of
# 2 and 16 neighbors, call the factory method with:
#
# LBPH.new(2, 16);
#
# And if you want a threshold (e.g. 123.0) call it with its default values:
#
# LBPH.new(1,8,8,8,123.0)
#
model = LBPH.new
model.train(images, labels)
# The following line predicts the label of a given test image:
predicted_label, predicted_confidence = model.predict(test_sample)
# To get the confidence of a prediction call the model with:
#
# predicted_label = -1;
# confidence = 0.0;
# model.predict(test_sample, predicted_label, confidence)
#
puts "Predicted class: #{predicted_label} / Actual class: #{test_label}"
# Sometimes you'll need to get/set internal model data,
# which isn't exposed by the public FaceRecognizer.
# Since each FaceRecognizer is derived from a Algorithm,
# you can query the data.
#
# First we'll use it to set the threshold of the FaceRecognizer
# to 0.0 without retraining the model. This can be useful if
# you are evaluating the model:
model.set_double('threshold', 0.0);
# Now the threshold of this model is set to 0.0. A prediction
# now returns -1, as it's impossible to have a distance below it
predicted_label, predicted_confidence = model.predict(test_sample)
puts "Predicted class = #{predicted_label}"
# Show some informations about the model, as there's no cool
# Model data to display as in Eigenfaces/Fisherfaces.
# Due to efficiency reasons the LBP images are not stored
# within the model:
puts 'Model Information:'
model_info = "\tLBPH(radius=#{model.get_int('radius')}, neighbors=#{model.get_int('neighbors')}, grid_x=#{model.get_int('grid_x')}, grid_y=#{model.get_int('grid_y')}, threshold=#{model.get_double('threshold')})"
puts model_info
# We could get the histograms for example:
histgrams = model.get_matvector('histograms');
# But should I really visualize it? Probably the length is interesting:
puts "Size of the histograms: #{histgrams[0].dims.reduce(&:*)}"

111
examples/facerec/readme.md Normal file
View file

@ -0,0 +1,111 @@
# Face recognition with ruby-opencv
This is a face recognition sample with ruby-opencv, which equivalent to the following OpenCV's tutorial.
[Face Recognition with OpenCV](http://docs.opencv.org/trunk/modules/contrib/doc/facerec/facerec_tutorial.html)
## Running samples
### 1. Get AT&T Facedatabase
Get AT&T Facedatabase from http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html and unzip it.
```sh
$ wget http://www.cl.cam.ac.uk/Research/DTG/attarchive/pub/data/att_faces.zip
$ unzip att_faces.zip
```
### 2. Prepare the data
Create a CSV file to run samples.
```sh
$ ruby create_csv.rb att_faces > at.txt
```
You will get a CSV file which contains lines composed of a filename followed by a ; followed by the label (as integer number).
```sh
$ cat at.txt
att_faces/s34/2.pgm;0
att_faces/s34/3.pgm;0
att_faces/s34/8.pgm;0
att_faces/s34/4.pgm;0
att_faces/s34/5.pgm;0
att_faces/s34/10.pgm;0
att_faces/s34/9.pgm;0
att_faces/s34/7.pgm;0
att_faces/s34/6.pgm;0
att_faces/s34/1.pgm;0
...
```
### 3. Run sample codes
#### Eigenfaces
```sh
$ mkdir output-eigenfaces
$ ruby facerec_eigenfaces.rb at.txt output-eigenfaces
```
You will get the predicted class, actual class and eignvalues shown in console.
```sh
Predicted class: 39 / Actual class: 39
Eigenvalue #0 = 2823424.500638128
Eigenvalue #1 = 2062015.3818895558
Eigenvalue #2 = 1090171.0771557507
Eigenvalue #3 = 892019.3644237233
Eigenvalue #4 = 818537.7917991373
Eigenvalue #5 = 539058.2364753223
Eigenvalue #6 = 390359.3231975121
Eigenvalue #7 = 373809.5486713626
Eigenvalue #8 = 314658.94374918053
Eigenvalue #9 = 288764.63018440653
```
The result images will be stored in **output-eigenfaces** .
#### Fisherfaces
```sh
$ mkdir output-fisherfaces
$ ruby facerec_fisherfaces.rb at.txt output-fisherfaces
```
You will get the predicted class, actual class and eignvalues like Eigenfaces sample.
The result images will be stored in **output-fisherfaces** .
#### Local Binary Patterns Histograms
```sh
$ ruby facerec_lbph.rb at.txt
```
You will get the predicted class, actual class, model information and size of the histgrams.
```
Predicted class: 39 / Actual class: 39
Predicted class = -1
Model Information:
LBPH(radius=1, neighbors=8, grid_x=8, grid_y=8, threshold=0.0)
Size of the histograms: 16384
```
## Credits
### The Database of Faces
The Database of Faces, formerly The ORL Database of Faces, contains a set of face images taken between April 1992 and April 1994. The database was used in the context of a face recognition project carried out in collaboration with the Speech, Vision and Robotics Group of the Cambridge University Engineering Department.
There are ten different images of each of 40 distinct subjects. For some subjects, the images were taken at different times, varying the lighting, facial expressions (open / closed eyes, smiling / not smiling) and facial details (glasses / no glasses). All the images were taken against a dark homogeneous background with the subjects in an upright, frontal position (with tolerance for some side movement).
The files are in PGM format. The size of each image is 92x112 pixels, with 256 grey levels per pixel. The images are organised in 40 directories (one for each subject), which have names of the form sX, where X indicates the subject number (between 1 and 40). In each of these directories, there are ten different images of that subject, which have names of the form Y.pgm, where Y is the image number for that subject (between 1 and 10).
A copy of the database can be retrieved from: http://www.cl.cam.ac.uk/research/dtg/attarchive/pub/data/att_faces.zip.

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
# A Demo Ruby/OpenCV Implementation of SURF
# See https://code.ros.org/trac/opencv/browser/tags/2.3.1/opencv/samples/c/find_obj.cpp
@ -100,8 +100,8 @@ puts 'Usage:'
puts "ruby #{__FILE__} <object_filename> <scene_filename>, default is box.png and box_in_scene.png"
puts
object_filename = (ARGV.size == 2) ? ARGV[0] : 'box.png'
scene_filename = (ARGV.size == 2) ? ARGV[1] : 'box_in_scene.png'
object_filename = (ARGV.size == 2) ? ARGV[0] : 'images/box.png'
scene_filename = (ARGV.size == 2) ? ARGV[1] : 'images/box_in_scene.png'
object, image = nil, nil
begin

View file

@ -7,7 +7,7 @@ include OpenCV
original_window = GUI::Window.new "original"
hough_window = GUI::Window.new "hough circles"
image = IplImage::load "stuff.jpg"
image = IplImage::load "images/stuff.jpg"
gray = image.BGR2GRAY
result = image.clone

View file

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

View file

Before

Width:  |  Height:  |  Size: 120 KiB

After

Width:  |  Height:  |  Size: 120 KiB

View file

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View file

Before

Width:  |  Height:  |  Size: 90 KiB

After

Width:  |  Height:  |  Size: 90 KiB

View file

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View file

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View file

@ -20,7 +20,7 @@ owindow = GUI::Window.new('original')
mwindow = GUI::Window.new('mask')
iwindow = GUI::Window.new('inpaint')
image = IplImage::load('inpaint.png')
image = IplImage::load('images/inpaint.png')
noimage = image.zero
b, g, r = image.split
original_mask = r.threshold(0x00, 0xFF, CV_THRESH_BINARY_INV) & b.threshold(0x00, 0xFF, CV_THRESH_BINARY_INV)

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
# A sample of matching SURF feature points using kd-tree
# See http://tech.groups.yahoo.com/group/OpenCV/message/62318
@ -11,8 +11,8 @@ USE_EXTENDED_DESCRIPTOR = true
THRESHOLD = 1500
DESCRIPTOR_SIZE = USE_EXTENDED_DESCRIPTOR ? 128 : 64
img1 = CvMat.load('lenna.jpg', CV_LOAD_IMAGE_GRAYSCALE)
img2 = CvMat.load('lenna-rotated.jpg', CV_LOAD_IMAGE_GRAYSCALE)
img1 = CvMat.load('images/lenna.jpg', CV_LOAD_IMAGE_GRAYSCALE)
img2 = CvMat.load('images/lenna-rotated.jpg', CV_LOAD_IMAGE_GRAYSCALE)
puts 'Extracting features from img1 using SURF...'
param = CvSURFParams.new(THRESHOLD, USE_EXTENDED_DESCRIPTOR)

26
examples/match_template.rb Executable file
View file

@ -0,0 +1,26 @@
#!/usr/bin/env ruby
# A demo of Ruby/OpenCV's match_template function
require 'opencv'
include OpenCV
puts 'This program demonstrates the match_template function'
puts 'Usage:'
puts "ruby #{__FILE__} <template_filename> <match_filename>"
puts
template_filename = (ARGV.size == 2) ? ARGV[0] : File.expand_path(File.dirname(__FILE__) + '/images/lena-eyes.jpg')
match_image_filename = (ARGV.size == 2) ? ARGV[1] : File.expand_path(File.dirname(__FILE__) + '/images/lena-256x256.jpg')
template = CvMat.load(template_filename)
match_image = CvMat.load(match_image_filename)
result = match_image.match_template(template, :sqdiff_normed)
pt1 = result.min_max_loc[2] # minimum location
pt2 = CvPoint.new(pt1.x + template.width, pt1.y + template.height)
match_image.rectangle!(pt1, pt2, :color => CvColor::Black, :thickness => 3)
window = GUI::Window.new('Display window') # Create a window for display.
window.show(match_image) # Show our image inside it.
GUI::wait_key # Wait for a keystroke in the window.

View file

@ -2,11 +2,11 @@ require 'opencv'
require 'benchmark'
include OpenCV
data = File.join(File.dirname(__FILE__), 'matching_to_many_images')
data = File.dirname(__FILE__)
query = IplImage.load File.join(data, 'query.png'), CV_LOAD_IMAGE_GRAYSCALE
query = CvMat.load File.join(data, 'query.png'), CV_LOAD_IMAGE_GRAYSCALE
image_files = ['1.png', '2.png', '3.png'].map{|f| File.join(data, 'train', f)}
images = image_files.map{|f| IplImage.load f, CV_LOAD_IMAGE_GRAYSCALE}
images = image_files.map{|f| CvMat.load f, CV_LOAD_IMAGE_GRAYSCALE}
matchs = query.match_descriptors(images)

286
ext/opencv/algorithm.cpp Normal file
View file

@ -0,0 +1,286 @@
/************************************************************
algorithm.cpp -
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#include <stdio.h>
#include "algorithm.h"
/*
* Document-class: OpenCV::Algorithm
*
*/
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_ALGORITHM
VALUE rb_klass;
VALUE
rb_class()
{
return rb_klass;
}
VALUE
rb_set_int(VALUE self, VALUE parameter, VALUE value)
{
Check_Type(parameter, T_STRING);
try {
ALGORITHM(self)->setInt(StringValueCStr(parameter), NUM2INT(value));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
VALUE
rb_set_double(VALUE self, VALUE parameter, VALUE value)
{
Check_Type(parameter, T_STRING);
try {
ALGORITHM(self)->setDouble(StringValueCStr(parameter), NUM2DBL(value));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
VALUE
rb_set_bool(VALUE self, VALUE parameter, VALUE value)
{
Check_Type(parameter, T_STRING);
try {
bool val = TRUE_OR_FALSE(value) ? true : false;
ALGORITHM(self)->setBool(StringValueCStr(parameter), val);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
VALUE
rb_set_string(VALUE self, VALUE parameter, VALUE value)
{
Check_Type(parameter, T_STRING);
Check_Type(value, T_STRING);
try {
ALGORITHM(self)->setString(StringValueCStr(parameter), StringValueCStr(value));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
VALUE
rb_set_mat(VALUE self, VALUE parameter, VALUE value)
{
Check_Type(parameter, T_STRING);
try {
CvMat* val = CVMAT_WITH_CHECK(value);
cv::Mat mat(val);
ALGORITHM(self)->setMat(StringValueCStr(parameter), mat);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
VALUE
rb_set_matvector(VALUE self, VALUE parameter, VALUE value)
{
Check_Type(parameter, T_STRING);
Check_Type(value, T_ARRAY);
try {
long len = RARRAY_LEN(value);
VALUE* value_ptr = RARRAY_PTR(value);
std::vector<cv::Mat> mat_vector;
for (int i = 0; i < len; i++) {
CvMat* val = CVMAT_WITH_CHECK(value_ptr[i]);
cv::Mat mat(val);
mat_vector.push_back(mat);
}
ALGORITHM(self)->setMatVector(StringValueCStr(parameter), mat_vector);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
VALUE
rb_set_algorithm(VALUE self, VALUE parameter, VALUE value)
{
Check_Type(parameter, T_STRING);
try {
ALGORITHM(self)->setAlgorithm(StringValueCStr(parameter), ALGORITHM(value));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
VALUE
rb_get_int(VALUE self, VALUE parameter)
{
Check_Type(parameter, T_STRING);
int value = 0;
try {
value = ALGORITHM(self)->getInt(StringValueCStr(parameter));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return INT2NUM(value);
}
VALUE
rb_get_double(VALUE self, VALUE parameter)
{
Check_Type(parameter, T_STRING);
double value = 0.0;
try {
value = ALGORITHM(self)->getDouble(StringValueCStr(parameter));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return DBL2NUM(value);
}
VALUE
rb_get_bool(VALUE self, VALUE parameter)
{
Check_Type(parameter, T_STRING);
bool value = false;
try {
value = ALGORITHM(self)->getBool(StringValueCStr(parameter));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return value ? Qtrue : Qfalse;
}
VALUE
rb_get_string(VALUE self, VALUE parameter)
{
Check_Type(parameter, T_STRING);
std::string value = "";
try {
value = ALGORITHM(self)->getString(StringValueCStr(parameter));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return rb_str_new_cstr(value.c_str());
}
VALUE
rb_get_mat(VALUE self, VALUE parameter)
{
Check_Type(parameter, T_STRING);
VALUE mat = Qnil;
try {
cv::Mat value = ALGORITHM(self)->getMat(StringValueCStr(parameter));
cv::Size size = value.size();
mat = cCvMat::new_object(size.height, size.width, value.type());
cv::Mat dst(CVMAT(mat));
value.copyTo(dst);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return mat;
}
VALUE
rb_get_matvector(VALUE self, VALUE parameter)
{
Check_Type(parameter, T_STRING);
VALUE array = Qnil;
try {
std::vector<cv::Mat> value = ALGORITHM(self)->getMatVector(StringValueCStr(parameter));
int len = value.size();
array = rb_ary_new2(len);
for (int i = 0; i < len; i++) {
cv::Mat m = value[i];
cv::Size size = m.size();
VALUE mat = cCvMat::new_object(size.height, size.width, m.type());
cv::Mat dst(CVMAT(mat));
m.copyTo(dst);
rb_ary_store(array, i, mat);
}
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return array;
}
VALUE
rb_name(VALUE self)
{
VALUE name = Qnil;
try {
name = rb_str_new_cstr(ALGORITHM(self)->name().c_str());
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return name;
}
void
define_ruby_class()
{
if (rb_klass)
return;
/*
* opencv = rb_define_module("OpenCV");
*
* note: this comment is used by rdoc.
*/
VALUE opencv = rb_module_opencv();
rb_klass = rb_define_class_under(opencv, "Algorithm", rb_cObject);
rb_define_method(rb_klass, "set_int", RUBY_METHOD_FUNC(rb_set_int), 2);
rb_define_method(rb_klass, "set_double", RUBY_METHOD_FUNC(rb_set_double), 2);
rb_define_method(rb_klass, "set_bool", RUBY_METHOD_FUNC(rb_set_bool), 2);
rb_define_method(rb_klass, "set_string", RUBY_METHOD_FUNC(rb_set_string), 2);
rb_define_method(rb_klass, "set_mat", RUBY_METHOD_FUNC(rb_set_mat), 2);
rb_define_method(rb_klass, "set_matvector", RUBY_METHOD_FUNC(rb_set_matvector), 2);
rb_define_method(rb_klass, "set_algorithm", RUBY_METHOD_FUNC(rb_set_algorithm), 2);
rb_define_method(rb_klass, "get_int", RUBY_METHOD_FUNC(rb_get_int), 1);
rb_define_method(rb_klass, "get_double", RUBY_METHOD_FUNC(rb_get_double), 1);
rb_define_method(rb_klass, "get_bool", RUBY_METHOD_FUNC(rb_get_bool), 1);
rb_define_method(rb_klass, "get_string", RUBY_METHOD_FUNC(rb_get_string), 1);
rb_define_method(rb_klass, "get_mat", RUBY_METHOD_FUNC(rb_get_mat), 1);
rb_define_method(rb_klass, "get_matvector", RUBY_METHOD_FUNC(rb_get_matvector), 1);
rb_define_method(rb_klass, "name", RUBY_METHOD_FUNC(rb_name), 0);
}
__NAMESPACE_END_ALGORITM
__NAMESPACE_END_OPENCV

38
ext/opencv/algorithm.h Normal file
View file

@ -0,0 +1,38 @@
/************************************************************
algorithm.h
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#ifndef RUBY_OPENCV_ALGORITHM_H
#define RUBY_OPENCV_ALGORITHM_H
#include "opencv.h"
#define __NAMESPACE_BEGIN_ALGORITHM namespace cAlgorithm {
#define __NAMESPACE_END_ALGORITM }
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_ALGORITHM
VALUE rb_class();
void define_ruby_class();
__NAMESPACE_END_ALGORITM
inline cv::Algorithm*
ALGORITHM(VALUE object)
{
cv::Algorithm *ptr;
Data_Get_Struct(object, cv::Algorithm, ptr);
return ptr;
}
__NAMESPACE_END_OPENCV
#endif // RUBY_OPENCV_ALGORITHM_H

View file

@ -107,21 +107,25 @@ VALUE
rb_retrieve(VALUE self)
{
VALUE image = Qnil;
IplImage *frame = NULL;
try {
IplImage *frame = cvRetrieveFrame(CVCAPTURE(self));
if (!frame)
if (!(frame = cvRetrieveFrame(CVCAPTURE(self)))) {
return Qnil;
image = cIplImage::new_object(cvSize(frame->width, frame->height),
CV_MAKETYPE(CV_8U, frame->nChannels));
if (frame->origin == IPL_ORIGIN_TL)
}
image = cIplImage::new_object(frame->width, frame->height,
CV_MAKETYPE(IPL2CV_DEPTH(frame->depth), frame->nChannels));
if (frame->origin == IPL_ORIGIN_TL) {
cvCopy(frame, CVARR(image));
else
}
else {
cvFlip(frame, CVARR(image));
}
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return image;
}
/*
@ -135,16 +139,19 @@ VALUE
rb_query(VALUE self)
{
VALUE image = Qnil;
IplImage *frame = NULL;
try {
IplImage *frame = cvQueryFrame(CVCAPTURE(self));
if (!frame)
if (!(frame = cvQueryFrame(CVCAPTURE(self)))) {
return Qnil;
image = cIplImage::new_object(cvSize(frame->width, frame->height),
CV_MAKETYPE(CV_8U, frame->nChannels));
if (frame->origin == IPL_ORIGIN_TL)
}
image = cIplImage::new_object(frame->width, frame->height,
CV_MAKETYPE(IPL2CV_DEPTH(frame->depth), frame->nChannels));
if (frame->origin == IPL_ORIGIN_TL) {
cvCopy(frame, CVARR(image));
else
}
else {
cvFlip(frame, CVARR(image));
}
}
catch (cv::Exception& e) {
raise_cverror(e);

View file

@ -184,6 +184,7 @@ rb_load_imageM(int argc, VALUE *argv, VALUE self)
/*
* Encodes an image into a memory buffer.
*
* @overload encode_image(ext, params = nil)
* @param ext [String] File extension that defines the output format ('.jpg', '.png', ...)
* @param params [Hash] - Format-specific parameters.
@ -1297,13 +1298,9 @@ rb_range_bang(VALUE self, VALUE start, VALUE end)
/*
* Changes shape of matrix/image without copying data.
* @overload reshape(params = nil)
* @param params [Hash] Parameters
* @option params [Integer] :channel (0) New number of channels.
* <tt>:channel => 0</tt> means that the number of channels remains unchanged.
* @option params [Integer] :rows (0) New number of rows.
* <tt>:rows => 0</tt> means that the number of rows remains unchanged unless
* it needs to be changed according to new_cn value.
* @overload reshape(cn, rows=0)
* @param cn [Integer] New number of channels. If the parameter is 0, the number of channels remains the same.
* @param rows [Integer] New number of rows. If the parameter is 0, the number of rows remains the same.
* @return [CvMat] Changed matrix
* @opencv_func cvReshape
* @example
@ -1312,15 +1309,13 @@ rb_range_bang(VALUE self, VALUE start, VALUE end)
* ch1 = mat.reshape(:channel => 1) #=> 9x3 1-channel matrix
*/
VALUE
rb_reshape(VALUE self, VALUE hash)
rb_reshape(int argc, VALUE *argv, VALUE self)
{
Check_Type(hash, T_HASH);
VALUE channel = LOOKUP_HASH(hash, "channel");
VALUE rows = LOOKUP_HASH(hash, "rows");
VALUE cn, rows;
CvMat *mat = NULL;
rb_scan_args(argc, argv, "11", &cn, &rows);
try {
mat = cvReshape(CVARR(self), RB_CVALLOC(CvMat), NIL_P(channel) ? 0 : NUM2INT(channel),
NIL_P(rows) ? 0 : NUM2INT(rows));
mat = cvReshape(CVARR(self), RB_CVALLOC(CvMat), NUM2INT(cn), IF_INT(rows, 0));
}
catch (cv::Exception& e) {
if (mat != NULL)
@ -2100,44 +2095,51 @@ rb_abs_diff(VALUE self, VALUE val)
/*
* Normalizes the norm or value range of an array.
*
* @overload normalize(alpha = 1.0, beta = 0.0, norm_type = 4, mask = nil)
* @param alpha [Number] Norm value to normalize to or the lower range boundary
* @overload normalize(alpha = 1.0, beta = 0.0, norm_type = NORM_L2, dtype = -1, mask = nil)
* @param alpha [Number] Norm value to normalize to or the lower range boundary
* in case of the range normalization.
* @param beta [Number] Upper range boundary in case of the range normalization.
* @param beta [Number] Upper range boundary in case of the range normalization.
* It is not used for the norm normalization.
* @param norm_type [Integer] Normalization type.
* @param mask [CvMat] Optional operation mask.
* @param norm_type [Integer] Normalization type.
* @param dtype [Integer] when negative, the output array has the same type as src;
* otherwise, it has the same number of channels as src and the depth
* @param mask [CvMat] Optional operation mask.
* @return [CvMat] Normalized array.
* @opencv_func cv::normalize
*/
VALUE
rb_normalize(int argc, VALUE *argv, VALUE self)
{
VALUE alphaVal, betaVal, normTypeVal, maskVal;
rb_scan_args(argc, argv, "04", &alphaVal, &betaVal, &normTypeVal, &maskVal);
const double alpha = alphaVal != Qnil ? NUM2DBL(alphaVal) : 1.0;
const double beta = betaVal != Qnil ? NUM2DBL(betaVal) : 0.0;
const int normType = normTypeVal != Qnil ? NUM2INT(normTypeVal) : cv::NORM_L2;
VALUE dest = new_mat_kind_object(cvGetSize(CVARR(self)), self);
VALUE alpha_val, beta_val, norm_type_val, dtype_val, mask_val;
rb_scan_args(argc, argv, "05", &alpha_val, &beta_val, &norm_type_val, &dtype_val, &mask_val);
double alpha = NIL_P(alpha_val) ? 1.0 : NUM2DBL(alpha_val);
double beta = NIL_P(beta_val) ? 0.0 : NUM2DBL(beta_val);
int norm_type = NIL_P(norm_type_val) ? cv::NORM_L2 : NUM2INT(norm_type_val);
int dtype = NIL_P(dtype_val) ? -1 : NUM2INT(dtype_val);
VALUE dst;
try {
const cv::Mat selfMat(CVMAT(self));
cv::Mat destMat(CVMAT(dest));
if (NIL_P(maskVal)) {
cv::normalize(selfMat, destMat, alpha, beta, normType);
cv::Mat self_mat(CVMAT(self));
cv::Mat dst_mat;
if (NIL_P(mask_val)) {
cv::normalize(self_mat, dst_mat, alpha, beta, norm_type, dtype);
}
else {
cv::Mat maskMat(MASK(maskVal));
cv::normalize(selfMat, destMat, alpha, beta, normType, -1, maskMat);
cv::Mat mask(MASK(mask_val));
cv::normalize(self_mat, dst_mat, alpha, beta, norm_type, dtype, mask);
}
} catch (cv::Exception& e) {
dst = new_mat_kind_object(cvGetSize(CVARR(self)), self, dst_mat.depth(), dst_mat.channels());
CvMat tmp = dst_mat;
cvCopy(&tmp, CVMAT(dst));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return dest;
return dst;
}
/*
@ -3749,9 +3751,9 @@ rb_resize(int argc, VALUE *argv, VALUE self)
VALUE
rb_warp_affine(int argc, VALUE *argv, VALUE self)
{
VALUE map_matrix, flags_val, option, fill_value;
VALUE map_matrix, flags_val, fill_value;
VALUE dest = Qnil;
if (rb_scan_args(argc, argv, "13", &map_matrix, &flags_val, &option, &fill_value) < 4)
if (rb_scan_args(argc, argv, "12", &map_matrix, &flags_val, &fill_value) < 3)
fill_value = INT2FIX(0);
CvArr* self_ptr = CVARR(self);
int flags = NIL_P(flags_val) ? (CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS) : NUM2INT(flags_val);
@ -3769,17 +3771,17 @@ rb_warp_affine(int argc, VALUE *argv, VALUE self)
/*
* Finds a perspective transformation between two planes.
*
* @overload find_homograpy(src_points, dst_points ,method = :all, ransac_reproj_threshold = 0, get_mask = nil)
* @param src_points [CvMat] Coordinates of the points in the original plane.
* @param dst_points [CvMat] Coordinates of the points in the target plane.
* @param method [Symbol] Method used to computed a homography matrix. The following methods are possible:
* * <tt>:all</tt> - a regular method using all the points
* * <tt>:ransac</tt> - RANSAC-based robust method
* * <tt>:lmeds</tt> - Least-Median robust method
* @param ransac_reproj_threshold [Number] Maximum allowed reprojection error to treat a point pair as
* an inlier (used in the RANSAC method only).
* @param get_mask [Boolean] If <tt>true</tt>, the optional output mask set by
* a robust method (<tt>:ransac</tt> or <tt>:lmeds</tt>) is returned additionally.
* @overload find_homography(src_points, dst_points, method = :all, ransac_reproj_threshold = 3, get_mask = false)
* @param src_points [CvMat] Coordinates of the points in the original plane.
* @param dst_points [CvMat] Coordinates of the points in the target plane.
* @param method [Symbol] Method used to computed a homography matrix. The following methods are possible:
* * <tt>:all</tt> - a regular method using all the points
* * <tt>:ransac</tt> - RANSAC-based robust method
* * <tt>:lmeds</tt> - Least-Median robust method
* @param ransac_reproj_threshold [Number] Maximum allowed reprojection error to treat a point pair as
* an inlier (used in the RANSAC method only).
* @param get_mask [Boolean] If <tt>true</tt>, the optional output mask set by
* a robust method (<tt>:ransac</tt> or <tt>:lmeds</tt>) is returned additionally.
* @return [CvMat, Array<CvMat>] The perspective transformation <tt>H</tt> between the source and the destination
* planes in <tt>CvMat</tt>.
* If <tt>method</tt> is <tt>:ransac</tt> or <tt>:lmeds</tt> and <tt>get_mask</tt> is <tt>true</tt>, the output mask
@ -3788,7 +3790,7 @@ rb_warp_affine(int argc, VALUE *argv, VALUE self)
* @opencv_func cvFindHomography
*/
VALUE
rb_find_homograpy(int argc, VALUE *argv, VALUE self)
rb_find_homography(int argc, VALUE *argv, VALUE self)
{
VALUE src_points, dst_points, method, ransac_reproj_threshold, get_status;
rb_scan_args(argc, argv, "23", &src_points, &dst_points, &method, &ransac_reproj_threshold, &get_status);
@ -3848,8 +3850,40 @@ rb_rotation_matrix2D(VALUE self, VALUE center, VALUE angle, VALUE scale)
}
/*
* Applies a perspective transformation to an image.
* call-seq:
* CvMat.get_perspective_transform(<i>from_points,to_points</i>) -> cvmat
*
* Calculates a perspective transform from four pairs of the corresponding points.
* Returns a matrix suitable for use with warp_perspective
*/
VALUE
rb_get_perspective_transform(VALUE self, VALUE source, VALUE dest)
{
Check_Type(source, T_ARRAY);
Check_Type(dest, T_ARRAY);
int count = RARRAY_LEN(source);
CvPoint2D32f* source_buff = ALLOCA_N(CvPoint2D32f, count);
CvPoint2D32f* dest_buff = ALLOCA_N(CvPoint2D32f, count);
for (int i = 0; i < count; i++) {
source_buff[i] = *(CVPOINT2D32F(RARRAY_PTR(source)[i]));
dest_buff[i] = *(CVPOINT2D32F(RARRAY_PTR(dest)[i]));
}
VALUE map_matrix = new_object(cvSize(3, 3), CV_MAKETYPE(CV_32F, 1));
try {
cvGetPerspectiveTransform(source_buff, dest_buff, CVMAT(map_matrix));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return map_matrix;
}
/*
* @overload warp_perspective(map_matrix, flags = CV_INTER_LINEAR | CV_WARP_FILL_OUTLIERS, fillval = 0)
* @param map_matrix [CvMat] 3x3 transformation matrix.
* @param flags [Integer] Combination of interpolation methods (<tt>CV_INTER_LINEAR</tt> or <tt>CV_INTER_NEAREST</tt>)
@ -4580,7 +4614,7 @@ rb_flood_fill_bang(int argc, VALUE *argv, VALUE self)
try {
CvSize size = cvGetSize(self_ptr);
// TODO: Change argument format to set mask
mask = new_object(size.width + 2, size.height + 2, CV_MAKETYPE(CV_8U, 1));
mask = new_object(size.height + 2, size.width + 2, CV_MAKETYPE(CV_8U, 1));
CvMat* mask_ptr = CVMAT(mask);
cvSetZero(mask_ptr);
cvFloodFill(self_ptr,
@ -5023,6 +5057,35 @@ rb_equalize_hist(VALUE self)
return dest;
}
/*
* call-seq:
* apply_color_map(colormap) -> cvmat
*
* Applies a GNU Octave/MATLAB equivalent colormap on a given image.
*
* Parameters:
* colormap - The colormap to apply.
*/
VALUE
rb_apply_color_map(VALUE self, VALUE colormap)
{
VALUE dst;
try {
cv::Mat dst_mat;
cv::Mat self_mat(CVMAT(self));
cv::applyColorMap(self_mat, dst_mat, NUM2INT(colormap));
CvMat tmp = dst_mat;
dst = new_object(tmp.rows, tmp.cols, tmp.type);
cvCopy(&tmp, CVMAT(dst));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return dst;
}
/*
* call-seq:
* match_template(<i>template[,method = :sqdiff]</i>) -> cvmat(result)
@ -5086,11 +5149,11 @@ rb_match_template(int argc, VALUE *argv, VALUE self)
* Compares two shapes(self and object). <i>object</i> should be CvMat or CvContour.
*
* A - object1, B - object2:
* * method=CV_CONTOUR_MATCH_I1
* * method=CV_CONTOURS_MATCH_I1
* I1(A,B)=sumi=1..7abs(1/mAi - 1/mBi)
* * method=CV_CONTOUR_MATCH_I2
* * method=CV_CONTOURS_MATCH_I2
* I2(A,B)=sumi=1..7abs(mAi - mBi)
* * method=CV_CONTOUR_MATCH_I3
* * method=CV_CONTOURS_MATCH_I3
* I3(A,B)=sumi=1..7abs(mAi - mBi)/abs(mAi)
*/
VALUE
@ -5134,7 +5197,6 @@ rb_match_descriptors(int argc, VALUE *argv, VALUE self)
{
VALUE images, detector_type, descriptor_type, matcher_type;
rb_scan_args(argc, argv, "13", &images, &detector_type, &descriptor_type, &matcher_type);
if (RARRAY_LEN(images) == 0) {
return rb_hash_new();
}
@ -5148,54 +5210,58 @@ rb_match_descriptors(int argc, VALUE *argv, VALUE self)
matcher_type = rb_str_new2("FlannBased");
}
cv::Mat queryImage = CVMAT(self);
std::vector<cv::Mat> trainImages;
for(int i=0; i < RARRAY_LEN(images); i++) {
trainImages.push_back(CVMAT_WITH_CHECK(RARRAY_PTR(images)[i]));
}
cv::Ptr<cv::FeatureDetector> featureDetector = cv::FeatureDetector::create(RSTRING_PTR(detector_type));
if (featureDetector.empty()) {
rb_raise(rb_eArgError, "Could not create feature detector by given detector type: %s", RSTRING_PTR(detector_type));
}
cv::Ptr<cv::DescriptorExtractor> descriptorExtractor = cv::DescriptorExtractor::create(RSTRING_PTR(descriptor_type));
if (descriptorExtractor.empty()) {
rb_raise(rb_eArgError, "Could not create descriptor extractor by given descriptor type: %s", RSTRING_PTR(descriptor_type));
}
cv::Ptr<cv::DescriptorMatcher> descriptorMatcher;
try {
descriptorMatcher = cv::DescriptorMatcher::create(RSTRING_PTR(matcher_type));
}
catch(cv::Exception& e) {
rb_raise(rb_eArgError, "Could not create descriptor matcher by given matcher type: %s", RSTRING_PTR(matcher_type));
}
std::vector<cv::KeyPoint> queryKeypoints;
std::vector<std::vector<cv::KeyPoint> > trainKeypoints;
featureDetector->detect(queryImage, queryKeypoints);
featureDetector->detect(trainImages, trainKeypoints);
cv::Mat queryDescriptors;
std::vector<cv::Mat> trainDescriptors;
descriptorExtractor->compute(queryImage, queryKeypoints, queryDescriptors);
descriptorExtractor->compute(trainImages, trainKeypoints, trainDescriptors);
std::vector<cv::DMatch> matches;
descriptorMatcher->add(trainDescriptors);
descriptorMatcher->train();
descriptorMatcher->match(queryDescriptors, matches);
VALUE _matches = rb_hash_new();
for (size_t i=0; i<matches.size(); i++) {
VALUE match = INT2FIX(matches[i].imgIdx);
VALUE count = rb_hash_lookup(_matches, match);
if (NIL_P(count)) {
count = INT2FIX(1);
} else {
count = INT2FIX(FIX2INT(count) + 1);
try {
cv::Mat queryImage(CVMAT(self));
std::vector<cv::Mat> trainImages;
for(int i = 0, n = RARRAY_LEN(images); i < n; i++) {
trainImages.push_back(CVMAT_WITH_CHECK(RARRAY_PTR(images)[i]));
}
cv::Ptr<cv::FeatureDetector> featureDetector = cv::FeatureDetector::create(StringValueCStr(detector_type));
if (featureDetector.empty()) {
rb_raise(rb_eArgError, "Could not create feature detector by given detector type: %s", StringValueCStr(detector_type));
}
cv::Ptr<cv::DescriptorExtractor> descriptorExtractor = cv::DescriptorExtractor::create(StringValueCStr(descriptor_type));
if (descriptorExtractor.empty()) {
rb_raise(rb_eArgError, "Could not create descriptor extractor by given descriptor type: %s", StringValueCStr(descriptor_type));
}
cv::Ptr<cv::DescriptorMatcher> descriptorMatcher;
try {
descriptorMatcher = cv::DescriptorMatcher::create(StringValueCStr(matcher_type));
}
catch(cv::Exception& e) {
rb_raise(rb_eArgError, "Could not create descriptor matcher by given matcher type: %s", StringValueCStr(matcher_type));
}
std::vector<cv::KeyPoint> queryKeypoints;
std::vector<std::vector<cv::KeyPoint> > trainKeypoints;
featureDetector->detect(queryImage, queryKeypoints);
featureDetector->detect(trainImages, trainKeypoints);
cv::Mat queryDescriptors;
std::vector<cv::Mat> trainDescriptors;
descriptorExtractor->compute(queryImage, queryKeypoints, queryDescriptors);
descriptorExtractor->compute(trainImages, trainKeypoints, trainDescriptors);
std::vector<cv::DMatch> matches;
descriptorMatcher->add(trainDescriptors);
descriptorMatcher->train();
descriptorMatcher->match(queryDescriptors, matches);
for (size_t i = 0, n = matches.size(); i < n; i++) {
VALUE match = INT2FIX(matches[i].imgIdx);
VALUE count = rb_hash_lookup(_matches, match);
if (NIL_P(count)) {
count = INT2FIX(1);
} else {
count = INT2FIX(FIX2INT(count) + 1);
}
rb_hash_aset(_matches, match, count);
}
rb_hash_aset(_matches, match, count);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return _matches;
}
@ -5625,6 +5691,55 @@ rb_extract_surf(int argc, VALUE *argv, VALUE self)
return rb_assoc_new(_keypoints, _descriptors);
}
/*
* call-seq:
* subspace_project(w, mean) -> cvmat
*/
VALUE
rb_subspace_project(VALUE self, VALUE w, VALUE mean)
{
VALUE projection;
try {
cv::Mat w_mat(CVMAT_WITH_CHECK(w));
cv::Mat mean_mat(CVMAT_WITH_CHECK(mean));
cv::Mat self_mat(CVMAT(self));
cv::Mat pmat = cv::subspaceProject(w_mat, mean_mat, self_mat);
projection = new_object(pmat.rows, pmat.cols, pmat.type());
CvMat tmp = pmat;
cvCopy(&tmp, CVMAT(projection));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return projection;
}
/*
* call-seq:
* subspace_reconstruct(w, mean) -> cvmat
*/
VALUE
rb_subspace_reconstruct(VALUE self, VALUE w, VALUE mean)
{
VALUE result;
try {
cv::Mat w_mat(CVMAT_WITH_CHECK(w));
cv::Mat mean_mat(CVMAT_WITH_CHECK(mean));
cv::Mat self_mat(CVMAT(self));
cv::Mat rmat = cv::subspaceReconstruct(w_mat, mean_mat, self_mat);
result = new_object(rmat.rows, rmat.cols, rmat.type());
CvMat tmp = rmat;
cvCopy(&tmp, CVMAT(result));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return result;
}
VALUE
new_object(int rows, int cols, int type)
{
@ -5728,7 +5843,7 @@ init_ruby_class()
rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("maximum_distance")), rb_float_new(1.0));
rb_hash_aset(find_fundamental_matrix_option, ID2SYM(rb_intern("desirable_level")), rb_float_new(0.99));
rb_define_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
rb_define_singleton_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load_imageM), -1);
// Ruby/OpenCV original functions
rb_define_method(rb_klass, "method_missing", RUBY_METHOD_FUNC(rb_method_missing), -1);
@ -5790,7 +5905,7 @@ init_ruby_class()
rb_define_method(rb_klass, "range", RUBY_METHOD_FUNC(rb_range), 2);
rb_define_method(rb_klass, "range!", RUBY_METHOD_FUNC(rb_range_bang), 2);
rb_define_method(rb_klass, "reshape", RUBY_METHOD_FUNC(rb_reshape), 1);
rb_define_method(rb_klass, "reshape", RUBY_METHOD_FUNC(rb_reshape), -1);
rb_define_method(rb_klass, "repeat", RUBY_METHOD_FUNC(rb_repeat), 1);
rb_define_method(rb_klass, "flip", RUBY_METHOD_FUNC(rb_flip), -1);
rb_define_method(rb_klass, "flip!", RUBY_METHOD_FUNC(rb_flip_bang), -1);
@ -5888,8 +6003,9 @@ init_ruby_class()
rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1);
rb_define_method(rb_klass, "warp_affine", RUBY_METHOD_FUNC(rb_warp_affine), -1);
rb_define_singleton_method(rb_klass, "rotation_matrix2D", RUBY_METHOD_FUNC(rb_rotation_matrix2D), 3);
rb_define_singleton_method(rb_klass, "get_perspective_transform", RUBY_METHOD_FUNC(rb_get_perspective_transform), 2);
rb_define_method(rb_klass, "warp_perspective", RUBY_METHOD_FUNC(rb_warp_perspective), -1);
rb_define_singleton_method(rb_klass, "find_homography", RUBY_METHOD_FUNC(rb_find_homograpy), -1);
rb_define_singleton_method(rb_klass, "find_homography", RUBY_METHOD_FUNC(rb_find_homography), -1);
rb_define_method(rb_klass, "remap", RUBY_METHOD_FUNC(rb_remap), -1);
rb_define_method(rb_klass, "log_polar", RUBY_METHOD_FUNC(rb_log_polar), -1);
@ -5928,6 +6044,7 @@ init_ruby_class()
rb_define_method(rb_klass, "inpaint", RUBY_METHOD_FUNC(rb_inpaint), 3);
rb_define_method(rb_klass, "equalize_hist", RUBY_METHOD_FUNC(rb_equalize_hist), 0);
rb_define_method(rb_klass, "apply_color_map", RUBY_METHOD_FUNC(rb_apply_color_map), 1);
rb_define_method(rb_klass, "match_template", RUBY_METHOD_FUNC(rb_match_template), -1);
rb_define_method(rb_klass, "match_shapes", RUBY_METHOD_FUNC(rb_match_shapes), -1);
rb_define_method(rb_klass, "match_descriptors", RUBY_METHOD_FUNC(rb_match_descriptors), -1);
@ -5947,6 +6064,9 @@ init_ruby_class()
rb_define_method(rb_klass, "extract_surf", RUBY_METHOD_FUNC(rb_extract_surf), -1);
rb_define_method(rb_klass, "subspace_project", RUBY_METHOD_FUNC(rb_subspace_project), 2);
rb_define_method(rb_klass, "subspace_reconstruct", RUBY_METHOD_FUNC(rb_subspace_reconstruct), 2);
rb_define_method(rb_klass, "save_image", RUBY_METHOD_FUNC(rb_save_image), -1);
rb_define_alias(rb_klass, "save", "save_image");
@ -5958,3 +6078,4 @@ init_ruby_class()
__NAMESPACE_END_OPENCV
__NAMESPACE_END_CVMAT

View file

@ -78,7 +78,7 @@ VALUE rb_set_identity_bang(int argc, VALUE *argv, VALUE self);
VALUE rb_range(VALUE self, VALUE start, VALUE end);
VALUE rb_range_bang(VALUE self, VALUE start, VALUE end);
/* Transforms and Permutations */
VALUE rb_reshape(VALUE self, VALUE hash);
VALUE rb_reshape(int argc, VALUE *argv, VALUE self);
VALUE rb_repeat(VALUE self, VALUE object);
VALUE rb_flip(int argc, VALUE *argv, VALUE self);
VALUE rb_flip_bang(int argc, VALUE *argv, VALUE self);
@ -175,8 +175,9 @@ VALUE rb_quadrangle_sub_pix(int argc, VALUE *argv, VALUE self);
VALUE rb_resize(int argc, VALUE *argv, VALUE self);
VALUE rb_warp_affine(int argc, VALUE *argv, VALUE self);
VALUE rb_rotation_matrix2D(VALUE self, VALUE center, VALUE angle, VALUE scale);
VALUE rb_get_perspective_transform(VALUE self, VALUE source, VALUE dest);
VALUE rb_warp_perspective(int argc, VALUE *argv, VALUE self);
VALUE rb_find_homograpy(int argc, VALUE *argv, VALUE self);
VALUE rb_find_homography(int argc, VALUE *argv, VALUE self);
VALUE rb_remap(int argc, VALUE *argv, VALUE self);
VALUE rb_log_polar(int argc, VALUE *argv, VALUE self);
@ -214,6 +215,9 @@ VALUE rb_dist_transform(int argc, VALUE *argv, VALUE self);
VALUE rb_inpaint(VALUE self, VALUE inpaint_method, VALUE mask, VALUE radius);
VALUE rb_equalize_hist(VALUE self);
VALUE rb_apply_color_map(VALUE self, VALUE colormap);
/* Matching*/
VALUE rb_match_template(int argc, VALUE *argv, VALUE self);
VALUE rb_match_shapes(int argc, VALUE *argv, VALUE self);
@ -236,6 +240,9 @@ VALUE rb_compute_correspond_epilines(VALUE klass, VALUE points, VALUE which_imag
/* Feature detection and description */
VALUE rb_extract_surf(int argc, VALUE *argv, VALUE self);
VALUE rb_subspace_project(VALUE self, VALUE w, VALUE mean);
VALUE rb_subspace_reconstruct(VALUE self, VALUE w, VALUE mean);
// HighGUI function
VALUE rb_save_image(int argc, VALUE *argv, VALUE self);

View file

@ -35,6 +35,22 @@ raise_compatible_typeerror(VALUE object, const char* expected_class_name)
rb_obj_classname(object), expected_class_name);
}
/*
* Allocates a memory buffer
* see cv::fastMalloc()
*/
void*
rbFastMalloc(size_t size)
{
uchar* udata = (uchar*)xmalloc(size + sizeof(void*) + CV_MALLOC_ALIGN);
if(!udata) {
rb_raise(rb_eNoMemError, "Failed to allocate memory");
}
uchar** adata = cv::alignPtr((uchar**)udata + 1, CV_MALLOC_ALIGN);
adata[-1] = udata;
return adata;
}
/*
* Allocates a memory buffer
* When memory allocation is failed, run GC and retry it
@ -42,26 +58,7 @@ raise_compatible_typeerror(VALUE object, const char* expected_class_name)
void*
rb_cvAlloc(size_t size)
{
void* ptr = NULL;
try {
ptr = cvAlloc(size);
}
catch(cv::Exception& e) {
if (e.code != CV_StsNoMem)
rb_raise(rb_eRuntimeError, "%s", e.what());
rb_gc_start();
try {
ptr = cvAlloc(size);
}
catch (cv::Exception& e) {
if (e.code == CV_StsNoMem)
rb_raise(rb_eNoMemError, "%s", e.what());
else
rb_raise(rb_eRuntimeError, "%s", e.what());
}
}
return ptr;
return rbFastMalloc(size);
}
/*
@ -69,28 +66,31 @@ rb_cvAlloc(size_t size)
* When memory allocation is failed, run GC and retry it
*/
CvMat*
rb_cvCreateMat(int height, int width, int type)
rb_cvCreateMat(int rows, int cols, int type)
{
CvMat* ptr = NULL;
CvMat* mat = NULL;
try {
ptr = cvCreateMat(height, width, type);
mat = cvCreateMatHeader(rows, cols, type);
if (mat) {
// see OpenCV's cvCreateData()
size_t step = mat->step;
size_t total_size = step * mat->rows + sizeof(int) + CV_MALLOC_ALIGN;
mat->refcount = (int*)rbFastMalloc(total_size);
mat->data.ptr = (uchar*)cvAlignPtr(mat->refcount + 1, CV_MALLOC_ALIGN);
*mat->refcount = 1;
}
else {
rb_raise(rb_eRuntimeError, "Failed to create mat header");
}
}
catch(cv::Exception& e) {
if (e.code != CV_StsNoMem)
rb_raise(rb_eRuntimeError, "%s", e.what());
rb_gc_start();
try {
ptr = cvCreateMat(height, width, type);
}
catch (cv::Exception& e) {
if (e.code == CV_StsNoMem)
rb_raise(rb_eNoMemError, "%s", e.what());
else
rb_raise(rb_eRuntimeError, "%s", e.what());
if (mat) {
cvReleaseMat(&mat);
}
rb_raise(rb_eRuntimeError, "%s", e.what());
}
return ptr;
return mat;
}
/*
@ -102,22 +102,20 @@ rb_cvCreateImage(CvSize size, int depth, int channels)
{
IplImage* ptr = NULL;
try {
ptr = cvCreateImage(size, depth, channels);
ptr = cvCreateImageHeader(size, depth, channels);
if (ptr) {
// see OpenCV's cvCreateData()
ptr->imageData = ptr->imageDataOrigin = (char*)rbFastMalloc((size_t)ptr->imageSize);
}
else {
rb_raise(rb_eRuntimeError, "Failed to create image header");
}
}
catch(cv::Exception& e) {
if (e.code != CV_StsNoMem)
rb_raise(rb_eRuntimeError, "%s", e.what());
rb_gc_start();
try {
ptr = cvCreateImage(size, depth, channels);
}
catch (cv::Exception& e) {
if (e.code == CV_StsNoMem)
rb_raise(rb_eNoMemError, "%s", e.what());
else
rb_raise(rb_eRuntimeError, "%s", e.what());
if (ptr) {
cvReleaseImage(&ptr);
}
rb_raise(rb_eRuntimeError, "%s", e.what());
}
return ptr;
}

View file

@ -11,6 +11,7 @@
#include <ruby.h>
#include "opencv2/core/core_c.h"
#include "opencv2/core/core.hpp"
#include "opencv2/core/internal.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2/imgproc/imgproc.hpp"

67
ext/opencv/eigenfaces.cpp Normal file
View file

@ -0,0 +1,67 @@
/************************************************************
eigenfaces.cpp -
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#include <stdio.h>
#include "eigenfaces.h"
/*
* Document-class: OpenCV::EigenFaces
*
*/
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_EIGENFACES
VALUE rb_klass;
VALUE
rb_class()
{
return rb_klass;
}
/*
* call-seq:
* EigenFaces.new(num_components=0, threshold=DBL_MAX)
*/
VALUE
rb_initialize(int argc, VALUE argv[], VALUE self)
{
VALUE num_components_val, threshold_val;
rb_scan_args(argc, argv, "02", &num_components_val, &threshold_val);
int num_components = NIL_P(num_components_val) ? 0 : NUM2INT(num_components_val);
double threshold = NIL_P(threshold_val) ? DBL_MAX : NUM2DBL(threshold_val);
free(DATA_PTR(self));
cv::Ptr<cv::FaceRecognizer> ptr = cv::createEigenFaceRecognizer(num_components, threshold);
DATA_PTR(self) = ptr;
cFaceRecognizer::guard_facerecognizer(DATA_PTR(self), ptr);
return self;
}
void
define_ruby_class()
{
if (rb_klass)
return;
/*
* opencv = rb_define_module("OpenCV");
*
* note: this comment is used by rdoc.
*/
VALUE opencv = rb_module_opencv();
rb_klass = rb_define_class_under(opencv, "EigenFaces", cFaceRecognizer::rb_class());
rb_define_alloc_func(rb_klass, cFaceRecognizer::allocate_facerecognizer);
rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
}
__NAMESPACE_END_EIGENFACES
__NAMESPACE_END_OPENCV

30
ext/opencv/eigenfaces.h Normal file
View file

@ -0,0 +1,30 @@
/************************************************************
eigenfaces.h
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#ifndef RUBY_OPENCV_EIGENFACES_H
#define RUBY_OPENCV_EIGENFACES_H
#include "opencv.h"
#define __NAMESPACE_BEGIN_EIGENFACES namespace cEigenFaces {
#define __NAMESPACE_END_EIGENFACES }
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_EIGENFACES
VALUE rb_class();
void define_ruby_class();
VALUE rb_initialize(int argc, VALUE argv[], VALUE self);
__NAMESPACE_END_EIGENFACES
__NAMESPACE_END_OPENCV
#endif // RUBY_OPENCV_EIGENFACES_H

View file

@ -5,14 +5,17 @@ def cv_version_suffix(incdir)
major, minor, subminor = nil, nil, nil
open("#{incdir}/opencv2/core/version.hpp", 'r') { |f|
f.read.lines.each { |line|
major = $1.to_s if line =~ /\A#define\s+CV_MAJOR_VERSION\s+(\d+)\s*\Z/
minor = $1.to_s if line =~ /\A#define\s+CV_MINOR_VERSION\s+(\d+)\s*\Z/
subminor = $1.to_s if line =~ /\A#define\s+CV_SUBMINOR_VERSION\s+(\d+)\s*\Z/
major = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_EPOCH|CV_MAJOR_VERSION)\s+(\d+)\s*\Z/
minor = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_MAJOR|CV_MINOR_VERSION)\s+(\d+)\s*\Z/
subminor = $1.to_s if line =~ /\A#define\s+(?:CV_VERSION_MINOR|CV_SUBMINOR_VERSION)\s+(\d+)\s*\Z/
}
}
major + minor + subminor
end
# Quick fix for 2.0.0
# @libdir_basename is set to nil and dir_config() sets invalid libdir '${opencv-dir}/' when --with-opencv-dir option passed.
@libdir_basename ||= 'lib'
incdir, libdir = dir_config("opencv", "/usr/local/include", "/usr/local/lib")
dir_config("libxml2", "/usr/include", "/usr/lib")
@ -67,9 +70,14 @@ opencv_headers.each {|header|
}
have_header("stdarg.h")
if $warnflags
$warnflags.slice!('-Wdeclaration-after-statement')
$warnflags.slice!('-Wimplicit-function-declaration')
end
# Quick fix for 1.8.7
$CFLAGS << " -I#{File.dirname(__FILE__)}/ext/opencv"
# Create Makefile
create_makefile("opencv", "./ext/opencv")
create_makefile('opencv')

View file

@ -0,0 +1,173 @@
/************************************************************
facerecognizer.cpp -
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#include <stdio.h>
#include "facerecognizer.h"
/*
* Document-class: OpenCV::FaceRecognizer
*
*/
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_FACERECOGNIZER
VALUE rb_klass;
std::map<void*, cv::Ptr<cv::FaceRecognizer> > ptr_guard_map;
void
guard_facerecognizer(void* data_ptr, cv::Ptr<cv::FaceRecognizer> ptr)
{
ptr_guard_map[data_ptr] = ptr;
}
void
release_facerecognizer(void *data_ptr)
{
ptr_guard_map[data_ptr].release();
ptr_guard_map.erase(data_ptr);
}
VALUE
allocate_facerecognizer(VALUE klass)
{
return Data_Wrap_Struct(klass, 0, release_facerecognizer, NULL);
}
VALUE
rb_class()
{
return rb_klass;
}
/*
* call-seq:
* train(src, labels)
*
* Trains a FaceRecognizer with given data and associated labels.
*/
VALUE
rb_train(VALUE self, VALUE src, VALUE labels)
{
Check_Type(src, T_ARRAY);
Check_Type(labels, T_ARRAY);
VALUE *src_ptr = RARRAY_PTR(src);
int src_size = RARRAY_LEN(src);
std::vector<cv::Mat> images;
for (int i = 0; i < src_size; i++) {
images.push_back(cv::Mat(CVMAT_WITH_CHECK(src_ptr[i])));
}
VALUE *labels_ptr = RARRAY_PTR(labels);
int labels_size = RARRAY_LEN(labels);
std::vector<int> local_labels;
for (int i = 0; i < labels_size; i++) {
local_labels.push_back(NUM2INT(labels_ptr[i]));
}
cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self);
try {
self_ptr->train(images, local_labels);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
/*
* call-seq:
* predict(src)
*
* Predicts a label and associated confidence (e.g. distance) for a given input image.
*/
VALUE
rb_predict(VALUE self, VALUE src)
{
cv::Mat mat = cv::Mat(CVMAT_WITH_CHECK(src));
cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self);
int label;
double confidence;
try {
self_ptr->predict(mat, label, confidence);
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return rb_ary_new3(2, INT2NUM(label), DBL2NUM(confidence));
}
/*
* call-seq:
* save(filename)
*
* Saves this model to a given filename, either as XML or YAML.
*/
VALUE
rb_save(VALUE self, VALUE filename)
{
Check_Type(filename, T_STRING);
cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self);
try {
char* s = StringValueCStr(filename);
self_ptr->save(std::string(s));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
/*
* call-seq:
* load(filename)
*
* Loads a FaceRecognizer and its model state.
*/
VALUE
rb_load(VALUE self, VALUE filename)
{
Check_Type(filename, T_STRING);
cv::FaceRecognizer *self_ptr = FACERECOGNIZER(self);
try {
char* s = StringValueCStr(filename);
self_ptr->load(std::string(s));
}
catch (cv::Exception& e) {
raise_cverror(e);
}
return Qnil;
}
void
define_ruby_class()
{
if (rb_klass)
return;
/*
* opencv = rb_define_module("OpenCV");
*
* note: this comment is used by rdoc.
*/
VALUE opencv = rb_module_opencv();
rb_klass = rb_define_class_under(opencv, "FaceRecognizer", cAlgorithm::rb_class());
rb_define_method(rb_klass, "train", RUBY_METHOD_FUNC(rb_train), 2);
rb_define_method(rb_klass, "predict", RUBY_METHOD_FUNC(rb_predict), 1);
rb_define_method(rb_klass, "save", RUBY_METHOD_FUNC(rb_save), 1);
rb_define_method(rb_klass, "load", RUBY_METHOD_FUNC(rb_load), 1);
}
__NAMESPACE_END_FACERECOGNIZER
__NAMESPACE_END_OPENCV

View file

@ -0,0 +1,46 @@
/************************************************************
facerecognizer.h
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#ifndef RUBY_OPENCV_FACERECOGNIZER_H
#define RUBY_OPENCV_FACERECOGNIZER_H
#include "opencv.h"
#define __NAMESPACE_BEGIN_FACERECOGNIZER namespace cFaceRecognizer {
#define __NAMESPACE_END_FACERECOGNIZER }
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_FACERECOGNIZER
VALUE rb_class();
void define_ruby_class();
VALUE rb_train(VALUE self, VALUE src, VALUE labels);
VALUE rb_predict(VALUE self, VALUE src);
VALUE rb_save(VALUE self, VALUE filename);
VALUE rb_load(VALUE self, VALUE filename);
void guard_facerecognizer(void* data_ptr, cv::Ptr<cv::FaceRecognizer> ptr);
void release_facerecognizer(void *data_ptr);
VALUE allocate_facerecognizer(VALUE klass);
__NAMESPACE_END_FACERECOGNIZER
inline cv::FaceRecognizer*
FACERECOGNIZER(VALUE object)
{
cv::FaceRecognizer *ptr;
Data_Get_Struct(object, cv::FaceRecognizer, ptr);
return ptr;
}
__NAMESPACE_END_OPENCV
#endif // RUBY_OPENCV_FACERECOGNIZER_H

View file

@ -0,0 +1,67 @@
/************************************************************
fisherfaces.cpp -
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#include <stdio.h>
#include "fisherfaces.h"
/*
* Document-class: OpenCV::FisherFaces
*
*/
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_FISHERFACES
VALUE rb_klass;
VALUE
rb_class()
{
return rb_klass;
}
/*
* call-seq:
* FisherFaces.new(num_components=0, threshold=DBL_MAX)
*/
VALUE
rb_initialize(int argc, VALUE argv[], VALUE self)
{
VALUE num_components_val, threshold_val;
rb_scan_args(argc, argv, "02", &num_components_val, &threshold_val);
int num_components = NIL_P(num_components_val) ? 0 : NUM2INT(num_components_val);
double threshold = NIL_P(threshold_val) ? DBL_MAX : NUM2DBL(threshold_val);
free(DATA_PTR(self));
cv::Ptr<cv::FaceRecognizer> ptr = cv::createFisherFaceRecognizer(num_components, threshold);
DATA_PTR(self) = ptr;
cFaceRecognizer::guard_facerecognizer(DATA_PTR(self), ptr);
return self;
}
void
define_ruby_class()
{
if (rb_klass)
return;
/*
* opencv = rb_define_module("OpenCV");
*
* note: this comment is used by rdoc.
*/
VALUE opencv = rb_module_opencv();
rb_klass = rb_define_class_under(opencv, "FisherFaces", cFaceRecognizer::rb_class());
rb_define_alloc_func(rb_klass, cFaceRecognizer::allocate_facerecognizer);
rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
}
__NAMESPACE_END_FISHERFACES
__NAMESPACE_END_OPENCV

30
ext/opencv/fisherfaces.h Normal file
View file

@ -0,0 +1,30 @@
/************************************************************
fisherfaces.h
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#ifndef RUBY_OPENCV_FISHERFACES_H
#define RUBY_OPENCV_FISHERFACES_H
#include "opencv.h"
#define __NAMESPACE_BEGIN_FISHERFACES namespace cFisherFaces {
#define __NAMESPACE_END_FISHERFACES }
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_FISHERFACES
VALUE rb_class();
void define_ruby_class();
VALUE rb_initialize(int argc, VALUE argv[], VALUE self);
__NAMESPACE_END_FISHERFACES
__NAMESPACE_END_OPENCV
#endif // RUBY_OPENCV_FISHERFACES_H

70
ext/opencv/lbph.cpp Normal file
View file

@ -0,0 +1,70 @@
/************************************************************
lbph.cpp -
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#include <stdio.h>
#include "lbph.h"
/*
* Document-class: OpenCV::LBPH
*
*/
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_LBPH
VALUE rb_klass;
VALUE
rb_class()
{
return rb_klass;
}
/*
* call-seq:
* LBPH.new(radius=1, neighbors=8, grid_x=8, grid_y=8, threshold=DBL_MAX) -> cvmat
*/
VALUE
rb_initialize(int argc, VALUE argv[], VALUE self)
{
VALUE radius_val, neighbors_val, grid_x_val, grid_y_val, threshold_val;
rb_scan_args(argc, argv, "05", &radius_val, &neighbors_val, &grid_x_val, &grid_y_val, &threshold_val);
int radius = NIL_P(radius_val) ? 1 : NUM2INT(radius_val);
int neighbors = NIL_P(neighbors_val) ? 8 : NUM2INT(neighbors_val);
int grid_x = NIL_P(grid_x_val) ? 8 : NUM2INT(grid_x_val);
int grid_y = NIL_P(grid_y_val) ? 8 : NUM2INT(grid_y_val);
double threshold = NIL_P(threshold_val) ? DBL_MAX : NUM2INT(threshold_val);
free(DATA_PTR(self));
cv::Ptr<cv::FaceRecognizer> ptr = cv::createLBPHFaceRecognizer(radius, neighbors, grid_x, grid_y, threshold);
DATA_PTR(self) = ptr;
cFaceRecognizer::guard_facerecognizer(DATA_PTR(self), ptr);
return self;
}
void
define_ruby_class()
{
if (rb_klass)
return;
/*
* opencv = rb_define_module("OpenCV");
*
* note: this comment is used by rdoc.
*/
VALUE opencv = rb_module_opencv();
rb_klass = rb_define_class_under(opencv, "LBPH", cFaceRecognizer::rb_class());
rb_define_alloc_func(rb_klass, cFaceRecognizer::allocate_facerecognizer);
rb_define_private_method(rb_klass, "initialize", RUBY_METHOD_FUNC(rb_initialize), -1);
}
__NAMESPACE_END_LBPH
__NAMESPACE_END_OPENCV

30
ext/opencv/lbph.h Normal file
View file

@ -0,0 +1,30 @@
/************************************************************
lbph.h
$Author: ser1zw $
Copyright (C) 2013 ser1zw
************************************************************/
#ifndef RUBY_OPENCV_LBPH_H
#define RUBY_OPENCV_LBPH_H
#include "opencv.h"
#define __NAMESPACE_BEGIN_LBPH namespace cLBPH {
#define __NAMESPACE_END_LBPH }
__NAMESPACE_BEGIN_OPENCV
__NAMESPACE_BEGIN_LBPH
VALUE rb_class();
void define_ruby_class();
VALUE rb_initialize(int argc, VALUE argv[], VALUE self);
__NAMESPACE_END_LBPH
__NAMESPACE_END_OPENCV
#endif // RUBY_OPENCV_LBPH_H

View file

@ -1,3 +0,0 @@
require (File.dirname(__FILE__) + '/opencv/version')
require 'opencv.so'

View file

@ -1,3 +0,0 @@
module OpenCV
VERSION = '0.0.8'
end

View file

@ -166,6 +166,11 @@ define_ruby_module()
rb_define_const(rb_module, "CV_MINOR_VERSION", INT2FIX(CV_MINOR_VERSION));
rb_define_const(rb_module, "CV_SUBMINOR_VERSION", INT2FIX(CV_SUBMINOR_VERSION));
rb_define_const(rb_module, "CV_VERSION_EPOCH", INT2FIX(CV_VERSION_EPOCH));
rb_define_const(rb_module, "CV_VERSION_MAJOR", INT2FIX(CV_VERSION_MAJOR));
rb_define_const(rb_module, "CV_VERSION_MINOR", INT2FIX(CV_VERSION_MINOR));
rb_define_const(rb_module, "CV_VERSION_REVISION", INT2FIX(CV_VERSION_REVISION));
/* 0: 8bit unsigned */
rb_define_const(rb_module, "CV_8U", INT2FIX(CV_8U));
/* 1: 8bit signed */
@ -180,7 +185,37 @@ define_ruby_module()
rb_define_const(rb_module, "CV_32F", INT2FIX(CV_32F));
/* 6: 64bit floating-point */
rb_define_const(rb_module, "CV_64F", INT2FIX(CV_64F));
/* Other depth */
rb_define_const(rb_module, "CV_8UC1", INT2FIX(CV_8UC1));
rb_define_const(rb_module, "CV_8UC2", INT2FIX(CV_8UC2));
rb_define_const(rb_module, "CV_8UC3", INT2FIX(CV_8UC3));
rb_define_const(rb_module, "CV_8UC4", INT2FIX(CV_8UC4));
rb_define_const(rb_module, "CV_8SC1", INT2FIX(CV_8SC1));
rb_define_const(rb_module, "CV_8SC2", INT2FIX(CV_8SC2));
rb_define_const(rb_module, "CV_8SC3", INT2FIX(CV_8SC3));
rb_define_const(rb_module, "CV_8SC4", INT2FIX(CV_8SC4));
rb_define_const(rb_module, "CV_16UC1", INT2FIX(CV_16UC1));
rb_define_const(rb_module, "CV_16UC2", INT2FIX(CV_16UC2));
rb_define_const(rb_module, "CV_16UC3", INT2FIX(CV_16UC3));
rb_define_const(rb_module, "CV_16UC4", INT2FIX(CV_16UC4));
rb_define_const(rb_module, "CV_16SC1", INT2FIX(CV_16SC1));
rb_define_const(rb_module, "CV_16SC2", INT2FIX(CV_16SC2));
rb_define_const(rb_module, "CV_16SC3", INT2FIX(CV_16SC3));
rb_define_const(rb_module, "CV_16SC4", INT2FIX(CV_16SC4));
rb_define_const(rb_module, "CV_32SC1", INT2FIX(CV_32SC1));
rb_define_const(rb_module, "CV_32SC2", INT2FIX(CV_32SC2));
rb_define_const(rb_module, "CV_32SC3", INT2FIX(CV_32SC3));
rb_define_const(rb_module, "CV_32SC4", INT2FIX(CV_32SC4));
rb_define_const(rb_module, "CV_32FC1", INT2FIX(CV_32FC1));
rb_define_const(rb_module, "CV_32FC2", INT2FIX(CV_32FC2));
rb_define_const(rb_module, "CV_32FC3", INT2FIX(CV_32FC3));
rb_define_const(rb_module, "CV_32FC4", INT2FIX(CV_32FC4));
rb_define_const(rb_module, "CV_64FC1", INT2FIX(CV_64FC1));
rb_define_const(rb_module, "CV_64FC2", INT2FIX(CV_64FC2));
rb_define_const(rb_module, "CV_64FC3", INT2FIX(CV_64FC3));
rb_define_const(rb_module, "CV_64FC4", INT2FIX(CV_64FC4));
/* Color types of loaded images */
rb_define_const(rb_module, "CV_LOAD_IMAGE_UNCHANGED", INT2FIX(CV_LOAD_IMAGE_UNCHANGED));
rb_define_const(rb_module, "CV_LOAD_IMAGE_GRAYSCALE", INT2FIX(CV_LOAD_IMAGE_GRAYSCALE));
@ -337,6 +372,19 @@ define_ruby_module()
rb_define_const(rb_module, "CV_CALIB_CB_FILTER_QUADS", INT2FIX(CV_CALIB_CB_FILTER_QUADS));
rb_define_const(rb_module, "CV_CALIB_CB_FAST_CHECK", INT2FIX(CV_CALIB_CB_FAST_CHECK));
/* Color map for cv::applyColorMap */
rb_define_const(rb_module, "COLORMAP_AUTUMN", INT2FIX(cv::COLORMAP_AUTUMN));
rb_define_const(rb_module, "COLORMAP_BONE", INT2FIX(cv::COLORMAP_BONE));
rb_define_const(rb_module, "COLORMAP_JET", INT2FIX(cv::COLORMAP_JET));
rb_define_const(rb_module, "COLORMAP_WINTER", INT2FIX(cv::COLORMAP_WINTER));
rb_define_const(rb_module, "COLORMAP_RAINBOW", INT2FIX(cv::COLORMAP_RAINBOW));
rb_define_const(rb_module, "COLORMAP_OCEAN", INT2FIX(cv::COLORMAP_OCEAN));
rb_define_const(rb_module, "COLORMAP_SUMMER", INT2FIX(cv::COLORMAP_SUMMER));
rb_define_const(rb_module, "COLORMAP_SPRING", INT2FIX(cv::COLORMAP_SPRING));
rb_define_const(rb_module, "COLORMAP_COOL", INT2FIX(cv::COLORMAP_COOL));
rb_define_const(rb_module, "COLORMAP_HSV", INT2FIX(cv::COLORMAP_HSV));
rb_define_const(rb_module, "COLORMAP_PINK", INT2FIX(cv::COLORMAP_PINK));
rb_define_const(rb_module, "COLORMAP_HOT", INT2FIX(cv::COLORMAP_HOT));
VALUE inversion_method = rb_hash_new();
/* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */
@ -706,6 +754,13 @@ extern "C" {
mOpenCV::cCvConnectedComp::init_ruby_class();
mOpenCV::cCvAvgComp::init_ruby_class();
mOpenCV::cCvHaarClassifierCascade::init_ruby_class();
mOpenCV::cAlgorithm::define_ruby_class();
mOpenCV::cFaceRecognizer::define_ruby_class();
mOpenCV::cEigenFaces::define_ruby_class();
mOpenCV::cFisherFaces::define_ruby_class();
mOpenCV::cLBPH::define_ruby_class();
mOpenCV::mGUI::define_ruby_module();
mOpenCV::mGUI::cWindow::define_ruby_class();
mOpenCV::mGUI::cTrackbar::define_ruby_class();

View file

@ -130,6 +130,12 @@ extern "C" {
#include "cvfeaturetree.h"
#include "algorithm.h"
#include "facerecognizer.h"
#include "eigenfaces.h"
#include "fisherfaces.h"
#include "lbph.h"
// GUI
#include "gui.h"
#include "window.h"

12
lib/opencv.rb Executable file
View file

@ -0,0 +1,12 @@
require (File.dirname(__FILE__) + '/opencv/version')
if RUBY_PLATFORM =~ /mingw|mswin/
major, minor, subminor = RUBY_VERSION.split('.')
begin
require "#{major}.#{minor}/opencv.so"
rescue LoadError
require 'opencv.so'
end
else
require 'opencv.so'
end

View file

@ -1,4 +1,4 @@
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
# Psych loader for avoiding loading problem
# (borrowed from Bundler 1.1.rc.7 https://github.com/carlhuda/bundler/blob/v1.1.rc.7/lib/bundler/psyched_yaml.rb )
#

3
lib/opencv/version.rb Executable file
View file

@ -0,0 +1,3 @@
module OpenCV
VERSION = '0.0.11'
end

File diff suppressed because one or more lines are too long

7524
test/eigenfaces_save.xml Normal file

File diff suppressed because it is too large Load diff

7530
test/fisherfaces_save.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'digest/md5'
require 'opencv'

4304
test/lbph_save.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
src_testdir = File.dirname(File.expand_path(__FILE__))

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'
@ -888,7 +888,7 @@ class TestCvMat < OpenCVTestCase
def test_reshape
m = create_cvmat(2, 3, CV_8U, 3)
vec = m.reshape(:rows => 1)
vec = m.reshape(0, 1)
assert_equal(6, vec.width)
assert_equal(1, vec.height)
size = m.width * m.height
@ -896,7 +896,7 @@ class TestCvMat < OpenCVTestCase
assert_cvscalar_equal(m[i], vec[i])
}
ch1 = m.reshape(:channel => 1)
ch1 = m.reshape(1)
assert_equal(9, ch1.width)
assert_equal(2, ch1.height)
@ -909,10 +909,11 @@ class TestCvMat < OpenCVTestCase
}
}
[DUMMY_OBJ, { :rows => DUMMY_OBJ }, { :channel => DUMMY_OBJ }].each { |arg|
assert_raise(TypeError) {
m.reshape(arg)
}
assert_raise(TypeError) {
m.reshape(DUMMY_OBJ)
}
assert_raise(TypeError) {
m.reshape(0, DUMMY_OBJ)
}
end
@ -2053,10 +2054,16 @@ class TestCvMat < OpenCVTestCase
assert_in_delta(x, mminmax[i][0], 0.001)
}
minf = mat.normalize(1, 0, CV_NORM_INF, CV_32FC3)
expected = [0.0, 0.333, 0.666, 1.0]
expected.each_with_index { |x, i|
assert_in_delta(x, minf[i][0], 0.001)
}
mask = mat.to_8u.zero
mask[0, 0] = CvScalar.new(255, 0, 0)
mask[1, 0] = CvScalar.new(255, 0, 0)
minf = mat.normalize(1, 0, CV_NORM_INF, mask)
minf = mat.normalize(1, 0, CV_NORM_INF, -1, mask)
expected = [0.0, 0.0, 1.0, 0.0]
expected.each_with_index { |x, i|
assert_in_delta(x, minf[i][0], 0.001)
@ -2794,11 +2801,11 @@ class TestCvMat < OpenCVTestCase
CvMat.find_fundamental_mat(mat1, mat2, CV_FM_LMEDS)].each { |f_mat|
assert_equal(3, f_mat.rows)
assert_equal(3, f_mat.cols)
expected = [-2.79e-05, -0.0009362, 0.0396139,
0.0010285, -2.48e-05, -0.3946452,
-0.0322220, 0.3695115, 1.0]
expected = [0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 1.0]
expected.each_with_index { |val, i|
assert_in_delta(val, f_mat[i][0], 1.0e-5)
assert_in_delta(val, f_mat[i][0], 0.1)
}
}
@ -2810,13 +2817,13 @@ class TestCvMat < OpenCVTestCase
assert_equal(1, status.rows)
assert_equal(num_points, status.cols)
expected_f_mat = [6.48e-05, 0.001502, -0.086036,
-0.001652, 3.86e-05, 0.638690,
0.059998, -0.597778, 1.0]
expected_fmat = [0.0, 0.0, 0.0,
0.0, 0.0, 0.0,
0.0, 0.0, 1.0]
expected_f_mat.each_with_index { |val, i|
assert_in_delta(val, f_mat[i][0], 1.0e-5)
assert_in_delta(val, f_mat[i][0], 0.1)
}
expected_status = [1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0]
expected_status = [0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1]
expected_status.each_with_index { |val, i|
assert_equal(val, status[i][0].to_i)
}
@ -2943,5 +2950,54 @@ class TestCvMat < OpenCVTestCase
CvMat.compute_correspond_epilines(mat1, 1, DUMMY_OBJ)
}
end
def test_apply_color_map
mat = CvMat.new(64, 256, :cv8u, 1)
mat.cols.times { |c|
mat.rows.times { |r|
mat[r, c] = c
}
}
results = []
[COLORMAP_AUTUMN, COLORMAP_BONE, COLORMAP_JET, COLORMAP_WINTER,
COLORMAP_RAINBOW, COLORMAP_OCEAN, COLORMAP_SUMMER, COLORMAP_SPRING,
COLORMAP_COOL, COLORMAP_HSV, COLORMAP_PINK, COLORMAP_HOT].each { |colormap|
cmap = mat.apply_color_map(colormap)
assert_equal(CvMat, cmap.class)
assert_equal(mat.rows, cmap.rows)
assert_equal(mat.cols, cmap.cols)
results << cmap
}
assert_raise(TypeError) {
mat.apply_color_map(DUMMY_OBJ)
}
# Uncomment the following line to show the result
# snap *results
end
def test_subspace_project
w = CvMat.new(10, 20, :cv32f, 1)
mean = CvMat.new(w.rows, 1, :cv32f, 1)
mat = CvMat.new(w.cols, w.rows, :cv32f, 1)
result = mat.subspace_project(w, mean)
assert_equal(CvMat, result.class)
assert_equal(w.cols, result.rows)
assert_equal(w.cols, result.cols)
end
def test_subspace_reconstruct
w = CvMat.new(10, 20, :cv32f, 1)
mean = CvMat.new(w.rows, 1, :cv32f, 1)
mat = CvMat.new(w.cols, w.cols, :cv32f, 1)
result = mat.subspace_reconstruct(w, mean)
assert_equal(CvMat, result.class)
assert_equal(w.cols, result.rows)
assert_equal(w.rows, result.cols)
end
end

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'
@ -450,6 +450,40 @@ class TestCvMat_imageprocessing < OpenCVTestCase
# snap mat0, mat1, mat2, mat3, mat4
end
def test_get_perspective_transform
from = [
OpenCV::CvPoint2D32f.new(540, 382),
OpenCV::CvPoint2D32f.new(802, 400),
OpenCV::CvPoint2D32f.new(850, 731),
OpenCV::CvPoint2D32f.new(540, 731),
]
to = [
OpenCV::CvPoint2D32f.new(0, 0),
OpenCV::CvPoint2D32f.new(233, 0),
OpenCV::CvPoint2D32f.new(233, 310),
OpenCV::CvPoint2D32f.new(0, 310),
]
transform = OpenCV::CvMat.get_perspective_transform(from, to)
assert_equal 3, transform.rows
assert_equal 3, transform.columns
expected = [
0.923332154750824,
0.0,
0.0,
1.4432899320127035e-15,
0.0,
0.0,
-498.599365234375,
0.0,
0.0,
]
3.times do |i|
3.times do |j|
assert_in_delta(expected.shift, transform[i][j], 0.001)
end
end
end
def test_rotation_matrix2D
mat1 = CvMat.rotation_matrix2D(CvPoint2D32f.new(10, 20), 60, 2.0)
expected = [1.0, 1.73205, -34.64102,
@ -1009,10 +1043,18 @@ class TestCvMat_imageprocessing < OpenCVTestCase
test_proc = lambda { |type, type_sym, expected_mat, expected_threshold|
mat1 = mat0.threshold(expected_threshold, 7, type)
mat2 = mat0.threshold(expected_threshold, 7, type_sym)
[mat1, mat2].each { |m|
expected_mat.each_with_index { |x, i|
assert_equal(x, m[i][0])
}
}
}
test_proc_with_otsu = lambda { |type, type_sym, expected_mat, expected_threshold|
mat3, th3 = mat0.threshold(5, 7, type | CV_THRESH_OTSU)
mat4, th4 = mat0.threshold(3, 7, type_sym, true)
mat5, th5 = mat0.threshold(5, 7, type | CV_THRESH_OTSU, true)
[mat1, mat2, mat3, mat4, mat5].each { |m|
[mat3, mat4, mat5].each { |m|
expected_mat.each_with_index { |x, i|
assert_equal(x, m[i][0])
}
@ -1021,36 +1063,62 @@ class TestCvMat_imageprocessing < OpenCVTestCase
assert_in_delta(expected_threshold, th, 0.001)
}
}
# Binary
expected = [0, 0, 0,
0, 0, 7,
7, 7, 7]
test_proc.call(CV_THRESH_BINARY, :binary, expected, 4)
expected = [0, 0, 0,
0, 7, 7,
7, 7, 7]
test_proc_with_otsu.call(CV_THRESH_BINARY, :binary, expected, 3)
# Binary inverse
expected = [7, 7, 7,
7, 7, 0,
0, 0, 0]
test_proc.call(CV_THRESH_BINARY_INV, :binary_inv, expected, 4)
expected = [7, 7, 7,
7, 0, 0,
0, 0, 0]
test_proc_with_otsu.call(CV_THRESH_BINARY_INV, :binary_inv, expected, 3)
# Trunc
expected = [0, 1, 2,
3, 4, 4,
4, 4, 4]
test_proc.call(CV_THRESH_TRUNC, :trunc, expected, 4)
expected = [0, 1, 2,
3, 3, 3,
3, 3, 3]
test_proc_with_otsu.call(CV_THRESH_TRUNC, :trunc, expected, 3)
# To zero
expected = [0, 0, 0,
0, 0, 5,
6, 7, 8]
test_proc.call(CV_THRESH_TOZERO, :tozero, expected, 4)
expected = [0, 0, 0,
0, 4, 5,
6, 7, 8]
test_proc_with_otsu.call(CV_THRESH_TOZERO, :tozero, expected, 3)
# To zero inverse
expected = [0, 1, 2,
3, 4, 0,
0, 0, 0]
test_proc.call(CV_THRESH_TOZERO_INV, :tozero_inv, expected, 4)
expected = [0, 1, 2,
3, 0, 0,
0, 0, 0]
test_proc_with_otsu.call(CV_THRESH_TOZERO_INV, :tozero_inv, expected, 3)
assert_raise(TypeError) {
mat0.threshold(DUMMY_OBJ, 2, :binary)
}
@ -1169,10 +1237,10 @@ class TestCvMat_imageprocessing < OpenCVTestCase
end
def test_flood_fill
mat0 = create_cvmat(128, 128, :cv8u, 1) { |j, i, c|
if (i >= 32 and i < 96) and (j >= 32 and j < 96)
mat0 = create_cvmat(128, 256, :cv8u, 1) { |j, i, c|
if (i >= 32 and i < 224) and (j >= 32 and j < 96)
CvScalar.new(255)
elsif (i >= 16 and i < 112) and (j >= 16 and j < 112)
elsif (i >= 16 and i < 240) and (j >= 16 and j < 112)
CvScalar.new(192)
else
CvScalar.new(128)
@ -1189,50 +1257,40 @@ class TestCvMat_imageprocessing < OpenCVTestCase
mat5, comp5, mask5 = mat05.flood_fill!(point, 0, CvScalar.new(0), CvScalar.new(64),
{:connectivity => 8, :fixed_range => true, :mask_only => true})
assert_equal('8c6a235fdf4c9c4f6822a45daac5b1af', hash_img(mat1))
assert_equal(5120.0, comp1.area)
assert_equal(9216.0, comp1.area)
assert_equal(16, comp1.rect.x)
assert_equal(16, comp1.rect.y)
assert_equal(96, comp1.rect.width)
assert_equal(224, comp1.rect.width)
assert_equal(96, comp1.rect.height)
assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), comp1.value)
assert_equal('1fd2537966283987b39c8b2c9d778383', hash_img(mask1))
assert_equal('7456e5de74bb8b4e783d04bbf1904644', hash_img(mat2))
assert_equal(12288.0, comp2.area)
assert_equal(20480.0, comp2.area)
assert_equal(0, comp2.rect.x)
assert_equal(0, comp2.rect.y)
assert_equal(128, comp2.rect.width)
assert_equal(256, comp2.rect.width)
assert_equal(128, comp2.rect.height)
assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), comp2.value)
assert_equal('847934f5170e2072cdfd63e16a1e06ad', hash_img(mask2))
assert_equal('df720005423762ca1b68e06571f58b21', hash_img(mat3))
assert_equal(9216.0, comp3.area)
assert_equal(21504.0, comp3.area)
assert_equal(16, comp3.rect.x)
assert_equal(16, comp3.rect.y)
assert_equal(96, comp3.rect.width)
assert_equal(224, comp3.rect.width)
assert_equal(96, comp3.rect.height)
assert_cvscalar_equal(CvScalar.new(0, 0, 0, 0), comp3.value)
assert_equal('7833f4c85c77056db71e33ae8072a1b5', hash_img(mat4))
assert_equal(9216.0, comp4.area)
assert_equal(21504.0, comp4.area)
assert_equal(16, comp4.rect.x)
assert_equal(16, comp4.rect.y)
assert_equal(96, comp4.rect.width)
assert_equal(224, comp4.rect.width)
assert_equal(96, comp4.rect.height)
assert_cvscalar_equal(CvScalar.new(220, 0, 0, 0), comp4.value)
assert_equal('b34b0269872fe3acde0e0c73e5cdd23b', hash_img(mask4))
assert_cvscalar_equal(CvScalar.new(228, 0, 0, 0), comp4.value)
assert_equal('7833f4c85c77056db71e33ae8072a1b5', hash_img(mat5))
assert_equal('7833f4c85c77056db71e33ae8072a1b5', hash_img(mat05))
assert_equal(9216.0, comp5.area)
assert_equal(21504.0, comp5.area)
assert_equal(16, comp5.rect.x)
assert_equal(16, comp5.rect.y)
assert_equal(96, comp5.rect.width)
assert_equal(224, comp5.rect.width)
assert_equal(96, comp5.rect.height)
assert_cvscalar_equal(CvScalar.new(220, 0, 0, 0), comp5.value)
assert_equal('b34b0269872fe3acde0e0c73e5cdd23b', hash_img(mask5))
assert_cvscalar_equal(CvScalar.new(228, 0, 0, 0), comp5.value)
assert_raise(TypeError) {
mat0.flood_fill(DUMMY_OBJ, 0)
@ -1613,7 +1671,9 @@ class TestCvMat_imageprocessing < OpenCVTestCase
def test_equalize_hist
mat = CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE)
result = mat.equalize_hist
assert_equal('de235065c746193d7f3de9359f63a7af', hash_img(result))
assert_equal(CvMat, result.class)
assert_equal(mat.rows, result.rows)
assert_equal(mat.cols, result.cols)
assert_raise(CvStsAssert) {
CvMat.new(10, 10, :cv32f, 3).equalize_hist

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'
@ -18,7 +18,7 @@ class TestCvMat_matching < OpenCVTestCase
end
def read_test_image(*path)
IplImage.load File.join(data_dir, *path), CV_LOAD_IMAGE_GRAYSCALE
CvMat.load File.join(data_dir, *path), CV_LOAD_IMAGE_GRAYSCALE
end
def test_match_descriptors

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

93
test/test_eigenfaces.rb Executable file
View file

@ -0,0 +1,93 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
require 'test/unit'
require 'opencv'
require 'date'
require File.expand_path(File.dirname(__FILE__)) + '/helper'
include OpenCV
# Tests for OpenCV::EigenFaces
class TestEigenFaces < OpenCVTestCase
def setup
@eigenfaces = EigenFaces.new
@eigenfaces_trained = EigenFaces.new
@images = [CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE)] * 2
@labels = [1, 2]
@eigenfaces_trained.train(@images, @labels)
end
def test_initialize
[EigenFaces.new, EigenFaces.new(1), EigenFaces.new(1, 99999)].each { |ef|
assert_equal(EigenFaces, ef.class)
}
assert_raise(TypeError) {
EigenFaces.new(DUMMY_OBJ)
}
assert_raise(TypeError) {
EigenFaces.new(1, DUMMY_OBJ)
}
end
def test_train
assert_nil(@eigenfaces.train(@images, @labels))
assert_raise(TypeError) {
@eigenfaces.train(DUMMY_OBJ, @labels)
}
assert_raise(TypeError) {
@eigenfaces.train(@images, DUMMY_OBJ)
}
end
def test_predict
predicted_label, predicted_confidence = @eigenfaces_trained.predict(@images[0])
assert_equal(@labels[0], predicted_label)
assert_in_delta(0.0, predicted_confidence, 0.01)
assert_raise(TypeError) {
@eigenfaces_trained.predict(DUMMY_OBJ)
}
end
def test_save
filename = "eigenfaces_save-#{DateTime.now.strftime('%Y%m%d%H%M%S')}.xml"
begin
@eigenfaces_trained.save(filename)
assert(File.exist? filename)
ensure
File.delete filename
end
assert_raise(TypeError) {
@eigenfaces_trained.save(DUMMY_OBJ)
}
end
def test_load
assert_nothing_raised {
@eigenfaces_trained.load('eigenfaces_save.xml')
}
assert_raise(TypeError) {
@eigenfaces_trained.load(DUMMY_OBJ)
}
end
def test_name
assert_equal('FaceRecognizer.Eigenfaces', @eigenfaces.name)
end
def test_get_mat
mat = @eigenfaces_trained.get_mat('eigenvalues')
assert_not_nil(mat)
assert_equal(CvMat, mat.class)
assert_raise(TypeError) {
@eigenfaces_trained.get_mat(DUMMY_OBJ)
}
end
end

93
test/test_fisherfaces.rb Executable file
View file

@ -0,0 +1,93 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
require 'test/unit'
require 'opencv'
require 'date'
require File.expand_path(File.dirname(__FILE__)) + '/helper'
include OpenCV
# Tests for OpenCV::FisherFaces
class TestFisherFaces < OpenCVTestCase
def setup
@fisherfaces = FisherFaces.new
@fisherfaces_trained = FisherFaces.new
@images = [CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE)] * 2
@labels = [1, 2]
@fisherfaces_trained.train(@images, @labels)
end
def test_initialize
[FisherFaces.new, FisherFaces.new(1), FisherFaces.new(1, 99999)].each { |ff|
assert_equal(FisherFaces, ff.class)
}
assert_raise(TypeError) {
FisherFaces.new(DUMMY_OBJ)
}
assert_raise(TypeError) {
FisherFaces.new(1, DUMMY_OBJ)
}
end
def test_train
assert_nil(@fisherfaces.train(@images, @labels))
assert_raise(TypeError) {
@fisherfaces.train(DUMMY_OBJ, @labels)
}
assert_raise(TypeError) {
@fisherfaces.train(@images, DUMMY_OBJ)
}
end
def test_predict
predicted_label, predicted_confidence = @fisherfaces_trained.predict(@images[0])
assert_equal(@labels[0], predicted_label)
assert_in_delta(0.0, predicted_confidence, 0.01)
assert_raise(TypeError) {
@fisherfaces_trained.predict(DUMMY_OBJ)
}
end
def test_save
filename = "fisherfaces_save-#{DateTime.now.strftime('%Y%m%d%H%M%S')}.xml"
begin
@fisherfaces_trained.save(filename)
assert(File.exist? filename)
ensure
File.delete filename
end
assert_raise(TypeError) {
@fisherfaces_trained.save(DUMMY_OBJ)
}
end
def test_load
assert_nothing_raised {
@fisherfaces.load('fisherfaces_save.xml')
}
assert_raise(TypeError) {
@fisherfaces.load(DUMMY_OBJ)
}
end
def test_name
assert_equal('FaceRecognizer.Fisherfaces', @fisherfaces.name)
end
def test_get_mat
mat = @fisherfaces_trained.get_mat('eigenvalues')
assert_not_nil(mat)
assert_equal(CvMat, mat.class)
assert_raise(TypeError) {
@fisherfaces_trained.get_mat(DUMMY_OBJ)
}
end
end

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'
@ -80,28 +80,24 @@ class TestIplImage < OpenCVTestCase
img4 = IplImage.decode(data, CV_LOAD_IMAGE_COLOR)
img5 = IplImage.decode(data_ary, CV_LOAD_IMAGE_COLOR)
img6 = IplImage.decode(data_mat, CV_LOAD_IMAGE_COLOR)
expected_hash = hash_img(expected)
[img1, img2, img3, img4, img5, img6].each { |img|
assert_equal(IplImage, img.class)
assert_equal(expected.rows, img.rows)
assert_equal(expected.cols, img.cols)
assert_equal(expected.channel, img.channel)
assert_equal(expected_hash, hash_img(img))
}
expected_c1 = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_GRAYSCALE)
img1c1 = IplImage.decode(data, CV_LOAD_IMAGE_GRAYSCALE)
img2c1 = IplImage.decode(data_ary, CV_LOAD_IMAGE_GRAYSCALE)
img3c1 = IplImage.decode(data_mat, CV_LOAD_IMAGE_GRAYSCALE)
expected_hash_c1 = hash_img(expected_c1)
[img1c1, img2c1, img3c1].each { |img|
assert_equal(IplImage, img.class)
assert_equal(expected_c1.rows, img.rows)
assert_equal(expected_c1.cols, img.cols)
assert_equal(expected_c1.channel, img.channel)
assert_equal(expected_hash_c1, hash_img(img))
}
assert_raise(TypeError) {

152
test/test_lbph.rb Executable file
View file

@ -0,0 +1,152 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
require 'test/unit'
require 'opencv'
require 'date'
require File.expand_path(File.dirname(__FILE__)) + '/helper'
include OpenCV
# Tests for OpenCV::LBPH
class TestLBPH < OpenCVTestCase
def setup
@lbph = LBPH.new
@lbph_trained = LBPH.new
@images = [CvMat.load(FILENAME_LENA256x256, CV_LOAD_IMAGE_GRAYSCALE)] * 2
@labels = [1, 2]
@lbph_trained.train(@images, @labels)
end
def test_initialize
[LBPH.new, LBPH.new(1), LBPH.new(1, 2, 3, 4, 5.0)].each { |lbph|
assert_equal(LBPH, lbph.class)
}
assert_raise(TypeError) {
LBPH.new(DUMMY_OBJ)
}
assert_raise(TypeError) {
LBPH.new(1, DUMMY_OBJ)
}
assert_raise(TypeError) {
LBPH.new(1, 2, DUMMY_OBJ)
}
assert_raise(TypeError) {
LBPH.new(1, 2, 3, DUMMY_OBJ)
}
assert_raise(TypeError) {
LBPH.new(1, 2, 3, 4, DUMMY_OBJ)
}
end
def test_train
assert_nil(@lbph.train(@images, @labels))
assert_raise(TypeError) {
@lbph.train(DUMMY_OBJ, @labels)
}
assert_raise(TypeError) {
@lbph.train(@images, DUMMY_OBJ)
}
end
def test_predict
predicted_label, predicted_confidence = @lbph_trained.predict(@images[0])
assert_equal(@labels[0], predicted_label)
assert_in_delta(0.0, predicted_confidence, 0.01)
assert_raise(TypeError) {
@lbph_trained.predict(DUMMY_OBJ)
}
end
def test_save
filename = "lbph_save-#{DateTime.now.strftime('%Y%m%d%H%M%S')}.xml"
begin
@lbph_trained.save(filename)
assert(File.exist? filename)
ensure
File.delete filename
end
assert_raise(TypeError) {
@lbph_trained.save(DUMMY_OBJ)
}
end
def test_load
assert_nothing_raised {
@lbph.load('lbph_save.xml')
}
assert_raise(TypeError) {
@lbph.load(DUMMY_OBJ)
}
end
def test_name
assert_equal('FaceRecognizer.LBPH', @lbph.name)
end
def test_get_int
assert_equal(1, @lbph.get_int('radius'))
assert_equal(8, @lbph.get_int('neighbors'))
assert_equal(8, @lbph.get_int('grid_x'))
assert_equal(8, @lbph.get_int('grid_y'))
assert_raise(TypeError) {
@lbph.get_int(DUMMY_OBJ)
}
end
def test_get_double
assert_equal(Float::MAX, @lbph.get_double('threshold'))
assert_raise(TypeError) {
@lbph.get_double(DUMMY_OBJ)
}
end
def test_get_matvector
histgrams = @lbph_trained.get_matvector('histograms')
assert_equal(Array, histgrams.class)
assert_equal(2, histgrams.size)
assert_equal(CvMat, histgrams[0].class)
assert_raise(TypeError) {
@lbph.get_matvector(DUMMY_OBJ)
}
end
def test_set_int
@lbph.set_int('radius', 2)
@lbph.set_int('neighbors', 3)
@lbph.set_int('grid_x', 4)
@lbph.set_int('grid_y', 5)
assert_equal(2, @lbph.get_int('radius'))
assert_equal(3, @lbph.get_int('neighbors'))
assert_equal(4, @lbph.get_int('grid_x'))
assert_equal(5, @lbph.get_int('grid_y'))
assert_raise(TypeError) {
@lbph.set_int(DUMMY_OBJ, 1)
}
assert_raise(TypeError) {
@lbph.set_int('radius', DUMMY_OBJ)
}
end
def test_set_double
@lbph.set_double('threshold', 1.0)
assert_in_delta(1.0, @lbph.get_double('threshold'), 0.001)
assert_raise(TypeError) {
@lbph.set_double(DUMMY_OBJ, 1.0)
}
assert_raise(TypeError) {
@lbph.set_double('threshold', DUMMY_OBJ)
}
end
end

View file

@ -1,5 +1,5 @@
#!/usr/bin/env ruby
# -*- mode: ruby; coding: utf-8-unix -*-
# -*- mode: ruby; coding: utf-8 -*-
require 'test/unit'
require 'opencv'
require File.expand_path(File.dirname(__FILE__)) + '/helper'

Some files were not shown because too many files have changed in this diff Show more