HOME > ブログ > CentOS5にOpenCVをインストール

CentOS5にOpenCVをインストール




顔認識機能が実装されているOpenCVをインストールして試してみました。
OpenCV(おーぷんしーぶい)とはインテルが開発・公開しているオープンソースのコンピュータビジョン向けライブラリ群のことで、
様々なプラットフォームで動かすことができる。
いつも使っているわけではないが、CentOS5にインストールしてPHPから利用するサンプルプログラムをさくっと作ってみたので、
以下詳細。
まずはCentOS5にOpenCVをインストール。
yumが使えるという記事もあったので、色々試してみたのだがCentOS5では無理っぽい。(方法はあるかもしれない、でもそれを記した記事にも出会えなかったしこれ以上は面倒くさいのでスルー)
だから素直にソースからインストールします。

# wget http://jaist.dl.sourceforge.net/sourceforge/opencvlibrary/opencv-1.0.0.tar.gz
# tar xvzf opencv-1.0.0.tar.gz
# cd opencv-1.0.0

解凍したファイルの一部が文字化けしているので、viで開いて修正。

1137行目 CvMemStorage*   storage;      /*storage for □foreground_regions□*/              \
    	↓
1137行目 CvMemStorage*   storage;      /*storage for foreground_regions*/              \

1137行目の「□」らしきところを削除して保存。

あとはお決まりで。(makeに結構時間がかかる)

# ./configure
# make
# make install

ライブラリのパス設定。viで新規ファイル「opencv.conf」を作り、「/usr/local/lib」とだけ記述して保存。

# vi /etc/ld.so.conf.d/opencv.conf
# ldconfig
# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:${PKG_CONFIG_PATH}

これでサーバへのOpenCVのインストールは終わり。


次はPHPから利用するためにPHPモジュール「face_detect」をインストールします。
このモジュール「face_detect」は個人の方が独自に作成し公開しているものですので、ありがたく利用させていただきます。

# wget http://www.netflowers.co.jp/face_detect/face_detect-0.0.1.tar.gz
# tar xvfz face_detect-0.0.1.tar.gz
# cd face_detect-0.0.1
# phpize    ← このコマンドがないと怒られたら「yum -y install php-devel」しておきます
# ./configure
# make
# make install

「/etc/php.ini」をviで編集し、以下の2行を追加。

extension_dir = "/usr/lib/php/modules/"
extension=face_detect.so

httpdを再起動すると、PHPの関数として「face_detect」が使えるようになります。

例えば、

$photo = "before.jpg";
$cascade = "/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml";
//顔の位置を検出
$faces = face_detect($photo ,$cascade);
echo print_r($faces);

とすると、「$faces」に指定した写真の中に認識した顔の数だけ、width、heightの大きさ、xyの座標が配列で返ってきます。

Array
(
    [0] => Array
        (
            [x] => 73
            [y] => 78
            [width] => 59
            [height] => 59
        )

    [1] => Array
        (
            [x] => 222
            [y] => 96
            [width] => 67
            [height] => 67
        )

    [2] => Array
        (
            [x] => 307
            [y] => 95
            [width] => 66
            [height] => 66
        )

)

こんな感じに。あとはこの大きさ座標に従って元の写真に違う画像を合成したりすれば認識した顔を隠したりすることが可能となる。

サンプルとしてさくっと、画像をアップロードし認識した顔すべてに笑い男マークをリアルタイムで上書きするというプログラムを作ってみたので、
以下ソース。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>顔認識サンプルプログラム</title>
</head>

<body>
<h1>顔認識サンプルプログラム</h1>
人物が撮影された写真をアップロードしてみてください。<br>
顔部分を自動で認識してあなたの目を盗みます。<br>

<form action="<?=$_SERVER['PHP_SELF']?>" method="post" ENCTYPE="multipart/form-data">
画像アップロード:<input type="file" name="file">
<input type="submit" value="送信">
<input type="hidden" name="upflg" value="1">
</form>
<br>
<br>
<?php
if($_POST['upflg']==1){

    if($_FILES['file']['tmp_name'] != ""){

        $pic_dir = "pic";//生成後画像の保存ディレクトリー
        $picture_over_org = "picture_over_org.gif";//認識した顔の上にかぶせる画像のオリジナル
        $picture_over = "picture_over.gif";//認識した顔の上にかぶせる画像
        $picture_result = $pic_dir."/picture_result".date("Ymdhis").".jpg";//かぶせた後の生成画像
        $cascade = "/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml";

        //画像保存
        move_uploaded_file($_FILES['file']['tmp_name'],$picture_result);

        //顔の位置を検出
        $faces = face_detect($picture_result ,$cascade);

        $num = 0;
        foreach($faces as $value){
                $wh = $value['width']."x".$value['height'];
                //外部プログラムとしてImageMagickに渡して認識した顔の大きさにかぶせ画像をあわせる
                system("convert -geometry $wh $picture_over_org $picture_over");
                $xy = "+".$value['x']."+".$value['y'];
                //外部プログラムとしてImageMagickに渡してさきほど作成したかぶせ画像の元の画像の左上から指定座標に合成
                system("composite -gravity northwest -geometry $xy $picture_over $picture_result $picture_result");
                $num++;
        }

        echo '<img src="'.$picture_result.'">';
        echo "<br>写真に".$num."箇所の顔が認識されました。<br>";
        echo "<br>";
        echo '<a href="'.$_SERVER['PHP_SELF'].'">< 戻る</a>';


    }else{
        echo "<br>";
        echo 'ファイルを指定ください。';
    }
}
?>
</body>
</html>

ImageMagickは必要となるのでない場合はインストールしてください。

で、こんな感じの画像が生成されるというわけです。


・感想
オープンソースなのでもちろん文句は言えないのだが、認識の精度としてはやっぱり不満が残る。言い換えれば実用に耐えうるような感じではないとはっきり言える。例えば、個人を特定できうる写真の顔すべてに自動でモザイクをかけるなどが最も考え付きやすくかつ実用でつかえるパターンだが、やってみるとすぐわかるが、かなり「キレイ」なかたちでそれが顔とわかるような写真でないと思ったようにモザイクはかけてくれない。少しうつむいていたり、横顔であったり、どアップであったりしてはほぼ機械はそれを顔として認識してくれないようである。これでは「こんなことができる!」とサンプルや遊びでしか使い道がない。
人間の顔を認識するするという行為は普段生活する上ではごく自然な行為でありとても簡単に行っているように思えるが、やはりコンピュータ上で同じ処理をするということは非常に難しいことなんだろうと改めて思う。
それにしても普段何気なく行っている、
・角度がかわったり陰影がかわったりしても同じ顔だと認識できる
・何年、何十年単位で人の顔は変わるにもかかわらず同じ人の顔だと認識できる
・はっきりと意識していないにも関わらず小さな差異によって違う顔だと認識できる
・自然や幾何学模様の中にも顔を発見できる
などは、あまねくすべての人が獲得している能力だけど、いつ獲得したのだろうか?また同属であるヒトだけにその能力発揮が制限されているのは何故なのか?(できる人もいるが猿やイルカや鹿などの顔の個体差などフツーわからない)

・参考記事
PHPで顔検出 - ネットに花を咲かせましょう。 会社作りました。
| Linux | Comment:0 |
コメント投稿












画像リロード
*半角の小英字、数字で構成されています