プログラミング的なSomething

プログラミング的なSomething

ITエンジニア(?)目線で生活・自転車・トレーニング話を綴ります

OpenCVを使った画像の顔検出

この土日でOpenCVを使った顔検出を実験してみたのでそのメモです。

環境

Ruby(1.9.2)
sinatra(1.3.1)
・OpenCV(2.3.1)

環境準備

OpenCVとそのライブラリの導入・ソースは以下のサイトを参考にさせていただきました。多謝。

macportsを使ってmacにopenCVを導入する(1)
ruby-opencv / ruby-opencv
Mac OS XでOpenCV x Ruby を使って顔認識

これでOpenCVを使う用意ができました。
リサイズやカットなど、基本的な画像処理には他にもRMagickと呼ばれるライブラリがあるので、併せて利用すると良いと思います。技評社のサイトが参考になります。

第26回 RMagickを用いた画像処理(1)リサイズ

コーディング

ディレクトリは以下のような感じです。

app.rb   
config.ru
opencv.rb
index.haml
upload.haml
images.haml
app.rb
require 'rubygems'
require 'sinatra'
require 'haml'
require './opencv.rb'

get '/' do
  haml :index
end

post '/upload' do
  if params[:file]
    #アップロードファイルのリネーム(hoge.jpg→detect.jpg)
    save_path = "detect.jpg"
    File.open(save_path,'wb') do |f|
      #アップロードしたファイルをdetect.jpgという名前で保存
      f.write params[:file][:tempfile].read
      #detect.jpgを読み込み顔検出を行う
      #顔検出後の画像は./public/images/に保存される
      Image_detect.new.detect
      p @mes = 'success'
    end
  else
    p @mes = 'failed'
  end
  haml :upload
  redirect 'images'
end

get '/images' do
  #detected.jpgを読み込む
  image = "./images/detected.jpg"
  @images = []
  @images << image
  haml :images
end
opencv.rb
require 'rubygems'
require 'opencv'
include OpenCV

class Image_detect
  def detect
    #画像の読み込み
    image = IplImage.load("detect.jpg")
    #学習データの読み込み
    faces = CvHaarClassifierCascade::load('/opt/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt2.xml')
    #顔認識→四角による描画
    faces.detect_objects(image.to_CvMat) do |rect|
      image.rectangle!(rect.top_left, rect.bottom_right, :color => CvColor::Red)
    end
    #画像を保存
    image.save_image("./public/images/detected.jpg")
  end
end
config.ru
require './app.rb'
require './opencv.rb'
run Sinatra::Application
index.haml
%html
 %body
  %form{:action => "./upload", :method => "post", :enctype => "multipart/form-data"}
   %input{:type => "file", :name => "file"}
   %input{:type => "submit", :name => "submit"}
upload.haml
%html
 %body
  %p= @mes
images.haml
%html
 %body
  - @images.each do |image_path|
   %img{:src => image_path}

index.haml上で画像をアップロードし、「送信」ボタンを押すと、顔検出された画像が表示されます。
出力結果の例がこちらです。

聖徳太子を例に顔検出しました。
ここまでは単純な顔検出になりますので、検出された部分に笑い男でも配置させるスクリプトを書いたり(ありがちな発想)、笑い男だけじゃなく、利用する人が好きな画像をアップして、それを顔に貼り付けられるような応用が効くといろいろ使えそう。