1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00
ruby-opencv/examples/facerec/facerec_lbph.rb
2014-01-13 17:42:52 +09:00

116 lines
3.8 KiB
Ruby
Executable file

#!/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(&:*)}"