ruby-opencvは5年ぐらい前に停止したopencvというgemを、ser1zwさんという方がOpenCV2.x系に対応させ、Ruby2.0に対応させ、と着実にアップデートしているプロジェクト。
先日これをみて、そういえば良いプロジェクトなのに全く試してなかったと思い出してまずインストールした。
ruby-opencvの進捗の話(2014年2月版) – ser1zw's blog
試しに作ったものはここに置いてある
https://github.com/shokai/ruby-opencv-study
感想
まだ大した事試してないけど、感想としては、ドキュメントが無い。でもOpenCV本体のドキュメント見てそのままRubyの常識にそって書き直したらふつうに動くのでドキュメントなくてもいいかなと思った。
Rubyだとそのオブジェクトが持っているメソッド一覧はObject#methodsなどで見れるし、
ruby-opencvのリポジトリをcloneしてきて git grep キーワード ext/ すればC++と対応してるRubyのメソッドはすぐ見つかる。
あとはそれぞれのC++ラッパーのオブジェクトにinspectメソッドがあると、見やすくて良くなるかと思った。例えばCvRectは4上下左右4座標が入っているんだけど、putsやpで4座標が標準出力できると便利だと思う。
Macにインストール
Mac (OSX 10.9.1)の場合、まずhomebrewでopencvを入れてからgem installしたら簡単にインストールできた。
% brew search opencv
% brew tap homebrew/science
% brew info opencv
opencv: stable 2.4.7.1
% brew install opencv
特にインストールオプション付けずにopencv 2.4.7.1が入った。
% gem install ruby-opencv
0.0.12が入った。
カメラでキャプチャして顔認識
最近追加されたEigenfacesやFisherfacesもあるけどとりあえず古典的なhaarlike cascadeでやってみる。
分類器は
/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml
をコピーしてきて使った。
ほぼ
サンプルまま。カメラでキャプチャして顔を認識する
capture_face_detect.rb
require 'opencv'
window = OpenCV::GUI::Window.new "face detect"
capture = OpenCV::CvCapture.open
detector = OpenCV::CvHaarClassifierCascade::load "./haarcascade_frontalface_default.xml"
loop do
image = capture.query
image = image.resize OpenCV::CvSize.new 640, 360
detector.detect_objects(image).each do |rect|
puts "detect!! : #{rect.top_left}, #{rect.top_right}, #{rect.bottom_left}, #{rect.bottom_right}"
image.rectangle! rect.top_left, rect.bottom_right, :color => OpenCV::CvColor::Red
end
window.show image
break if OpenCV::GUI::wait_key(100)
end
ウィンドウが開いて顔の部分に赤枠がでる
顔認識して画像ファイルを保存
Rubyなのでサーバーで使うような事を考えると、windowで画像を表示するのではなく顔認識した結果をファイルに書き出したほうがそれっぽいかなあとか考えてた
face_detect.rb
require 'opencv'
if ARGV.size < 2
STDERR.puts " % ruby #{$0} input.jpg output.jpg"
exit 1
end
input_filename = ARGV.shift
output_filename = ARGV.shift
image = OpenCV::IplImage::load input_filename
haar_xml_file = File.expand_path File.dirname(__FILE__), 'haarcascade_frontalface_default.xml'
detector = OpenCV::CvHaarClassifierCascade::load haar_xml_file
detector.detect_objects(image).each do |rect|
puts "detect!! : #{rect.top_left}, #{rect.top_right}, #{rect.bottom_left}, #{rect.bottom_right}"
image.rectangle! rect.top_left, rect.bottom_right, :color => OpenCV::CvColor::Red
end
image.save output_filename
% ruby face_detect.rb input.jpg output.jpg
結果
detect!! : <OpenCV::CvPoint:(125,9)>, <OpenCV::CvPoint:(472,9)>, <OpenCV::CvPoint:(125,356)>, <OpenCV::CvPoint:(472,356)>
シンプルに書けてよい。