Image::ObjectDetectを使った顔認識プログラム

Perl版のOpenCV、Image::ObjectDetectを使った顔認識を試してみました。

まずは顔にエフェクトをかけてプライバシーを守るWebサービスの作り方を参考にMacPorts用にパスを変えて、

CPANモジュール

  • Imagerインストール
  • Image::ObjectDetectインストール

http://search.cpan.org/~jiro/Image-ObjectDetect-0.11/lib/Image/ObjectDetect.pm


cpanのinstall Image::ObjectDetectでエラーが起きた。

Checking if your kit is complete...
Looks good
Writing Makefile for Image:jectDetect
cp lib/Image/ObjectDetect.pm blib/lib/Image/ObjectDetect.pm
cp lib/Image/ObjectDetect.xs blib/lib/Image/ObjectDetect.xs
/opt/local/bin/perl /opt/local/lib/perl5/5.8.8/ExtUtils/xsubpp  -typemap /opt/local/lib/perl5/5.8.8/ExtUtils/typemap  ObjectDetect.xs > ObjectDetect.xsc && mv ObjectDetect.xsc ObjectDetect.c
cc -c   -I/opt/local/include/opencv  -Isrc -I/opt/local/include/opencv   -O3   -DVERSION=\"0.11\" -DXS_VERSION=\"0.11\"  "-I/opt/local/lib/perl5/5.8.8/darwin-2level/CORE"   ObjectDetect.c
In file included from ObjectDetect.xs:/opt/local/lib/perl5/5.8.8/darwin-2level/CORE/cv.h:rror:definition of ‘struct xpvcv’
ObjectDetect.xs: function ‘XS_Image__ObjectDetect_new’:bjectDetect.xs:rror:#65533;vHaarClassifierCascade’ undeclared (first use in this function)
ObjectDetect.xs:rror:ach undeclared identifier is reported only once
ObjectDetect.xs:rror:r each function it appears in.)
ObjectDetect.xs:rror:#65533;ascade’ undeclared (first use in this function)
ObjectDetect.xs: function ‘XS_Image__ObjectDetect_xs_detect’:bjectDetect.xs:rror:#65533;vHaarClassifierCascade’ undeclared (first use in this function)
ObjectDetect.xs:rror:#65533;ascade’ undeclared (first use in this function)
ObjectDetect.xs:rror:#65533;V_BGR2GRAY’ undeclared (first use in this function)
ObjectDetect.xs:rror:ntax error before ‘)’ token
ObjectDetect.xs:rror:#65533;V_HAAR_DO_CANNY_PRUNING’ undeclared (first use in this function)
ObjectDetect.xs:arning:signment makes pointer from integer without a cast
ObjectDetect.xs: function ‘XS_Image__ObjectDetect_DESTROY’:bjectDetect.xs:rror:#65533;vHaarClassifierCascade’ undeclared (first use in this function)
ObjectDetect.xs:rror:#65533;ascade’ undeclared (first use in this function)
ObjectDetect.xs:rror:ntax error before ‘)’ token
make:* [ObjectDetect.o] Error 1
  JIRO/Image-ObjectDetect-0.11.tar.gz
  /usr/bin/make -- NOT OK
Running make test
  Can't test without successful make
Running make install
  Make had returned bad status, install seems impossible
Failed during this command:
 JIRO/Image-ObjectDetect-0.11.tar.gz          : make NO


どうやらそれぞれのcv.hのパスが下記の2カ所ある為に混同してしまい、インストールに失敗するとのこと。

  • /opt/local/include/opencv/cv.h
  • /opt/local/lib/perl5/5.8.8/darwin-2level/CORE/cv.h

OpenCV, Image::ObjectDetectをMacにインスト - bokut.inのエントリーのおかげで解決しました。


解決までの道のり

cpan[1]> look Image::ObjectDetect 
(中略)
bash-3.2# cp lib/Image/ObjectDetect.xs lib/Image/ObjectDetect.xs.orig
bash-3.2# ed lib/Image/ObjectDetect.xs 
2391
7
#include "cv.h"
s|cv.h|../opencv/cv.h|
7
#include "../opencv/cv.h"
w
2401
q
bash-3.2# diff lib/Image/ObjectDetect.xs.orig lib/Image/ObjectDetect.xs 
7c7
< #include "cv.h"
---
> #include "../opencv/cv.h"

make installだとエラーが出たので、perl Makefile.PLとしてからinstallする。

bash-3.2# sudo make install
make: *** No rule to make target `install'.  Stop.

こちらでインストール完了
bash-3.2# sudo perl Makefile.PL 
Checking if your kit is complete...
Looks good
Writing Makefile for Image:jectDetect
bash-3.2# make install


Image::ObjectDetectでビークル風なものもすぐ作れました。

face_detector.pl

#!/usr/bin/perl                                                           
use strict;                                                               
use warnings;                                                             
                                                                          
use Smart::Comments;                                                      
use Imager;                                                               
use Image::ObjectDetect;                                                  
                                                                          
my $file = 'sample.jpg';                                                 
my $image = Imager->new->read(file => $file);                             
my $cascade = '/opt/local/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml';                                                              
my $detector = Image::ObjectDetect->new($cascade);                        
my @faces = $detector->detect($file);                                     
                                                                          
for my $face (@faces) {                                                   
    my $file2 = 'hidaka.jpg';                                             
    my $image2 = Imager->new->read(file => $file2);                       
    $image2 = $image2->scale(xpixels => $face->{width}, ypixels => $face->
{height});                                                                
    $image->paste(left => $face->{x}, top => $face->{y}, src => $image2); 
}                                                                         
                                                                          
$image->write(file => 'output.jpg');                                
                                                                          
print "Content-type: text/html\n\n";                                      
print "<html lang=\"ja\">\n";                                             
print "<head>\n";                                                         
print "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=EUC-JP\">\n";                                                                 
print "<TITLE>顔をビークル風にしてみるテスト</TITLE>\n";                  
print "</HEAD>\n";                                                        
print "<BODY>\n";                                                         
print "<p>変換した画像が下に表示されます。</p>\n";                        
print "<br>\n";                                                           
print "<img src=\"output.jpg\">\n";                                 
print "</BODY>\n";                                                        
print "</HTML>\n";                                                        

OpenCV関連の参考エントリー

とても参考になりました。ありがとうございます。