ちょっとしたことでOpenCVを使いたいなと思って, せっかくなのでrubyからOpenCVを利用できないかなと思って調べてみたらruby-opencvなるものがあったので使ってみた.
動作環境
- OS
- MacOSX 10.8
- Ruby
- ruby 2.0.0p0
- OpenCV
- 2.4.6
ruby-opencvのインストール
bundler経由でインストールします.
source 'https://rubygems.org'
gem 'ruby-oepncv'
bundle install
とかでインストールできます.
顔検出する
OpenCVにある識別器を用いて顔検出します. 以下のソースコードで実現できます.
detector = CvHaarClassifierCascade::load './haarcascade_frontalface_alt.xml'
detector.detect_objects(image).each do |region|
# regionに顔として検出した領域の矩形情報が格納されているのでそれを使って色々処理
end
region
はwidth
, heigit
, left_top
, right_bottom
などの変数を持っているので, それを用いて処理をすることになるでしょう.
ちなみに'./haarcascade_frontalface_alt.xml'
は顔検出用の学習データとなりますが, この学習データを変更することで様々なものを識別させることができます.
サンプル
以下は第1引数に与えれた画像から顔検出して, 抽出した領域に笑い男のロゴを貼り付けるサンプルです.
#!/usr/bin/env ruby
require 'opencv'
include OpenCV
if ARGV.size != 1
puts "Usage: ruby #{__FILE__} Image"
exit
end
image = nil
image_laugh = nil
begin
image = IplImage.load ARGV[0], 1
image_laugh = IplImage.load './laugh.png', 1
rescue
puts 'Could not open or find the image.'
exit
end
detector = CvHaarClassifierCascade::load './haarcascade_frontalface_alt.xml'
detector.detect_objects(image).each do |region|
resized_image = image_laugh.resize region
image.set_roi region
(resized_image.rows * resized_image.cols).times do |i|
if resized_image[i][0].to_i > 0 or resized_image[i][1].to_i > 0 or resized_image[i][2].to_i > 0
image[i] = resized_image[i]
end
image.reset_roi
end
window = GUI::Window.new('laugh.rb')
window.show image
GUI::wait_key
実行結果
以下は上記のサンプルに自分のFacebookプロフィール画像を食わせた結果です. うまくハックで来てますね :)
ちなみにデフォルトの学習データでは誤識別をするケースがありますので,
アプリケーションによっては, 例えばしきい値となる矩形幅を指定しておいてそれ以下なら処理しない, とか工夫が必要かもしれません.
感想
OpenCVがRubyから使えるということでその手軽さが良いなと思いました.
しかしまだまだ開発途中なのかAPIが少なく, またドキュメントがほぼない? のでOpenCVの知識と実際のソースを読まないと進められないという難しさは感じました.