ログイン TOPに戻る
PHPの拡張は初めて作ったんだけど、
codegenというのを使うと結構簡単に出来る。

以下、顔検出プラグインを作るまで。

codegenをインストールする。
# pear install -a codegen_pecl

以下のxmlファイルを、face_detect.xmlとして保存。

<?xml version="1.0" ?>
<extension name="face_detect" version="0.0.1">
<deps language="c" platform="all">
<with defaults="/usr:/usr/local" testfile="include/opencv/cv.h">
<header name="opencv/cv.h" />
<header name="opencv/highgui.h" />

<lib name="cv" platform="all" />
<lib name="cvaux" platform="all" />
<lib name="highgui" platform="all" />
<lib name="cxcore" platform="all" />
<lib name="ml" platform="all" />

</with>
</deps>
<function name="face_detect">
<proto>array face_detect(string filename,string cascade_name)</proto>
<code>
<![CDATA[

int i;
CvHaarClassifierCascade* cascade = 0;
IplImage *img, *gray;
CvMemStorage *storage;
CvSeq *objects;
CvRect *rect;


cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0 );
if( !cascade ){
RETURN_FALSE;
}

img = cvLoadImage(filename,1);
if( !img ){
RETURN_FALSE;
}

gray = cvCreateImage(cvSize(img->width, img->height), 8, 1);
cvCvtColor(img, gray, CV_BGR2GRAY);
cvEqualizeHist(gray, gray);

storage = cvCreateMemStorage(0);

objects = cvHaarDetectObjects(gray, cascade, storage,
1.1, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0, 0));

array_init(return_value);


for (i = 0; i < (objects ? objects->total : 0); i++) {
rect = (CvRect *) cvGetSeqElem(objects, i);

zval *new_array;
MAKE_STD_ZVAL(new_array);
array_init(new_array);

add_assoc_long(new_array,"x",rect->x);
add_assoc_long(new_array,"y",rect->y);
add_assoc_long(new_array,"width",rect->width);
add_assoc_long(new_array,"height",rect->height);

add_next_index_zval(return_value, new_array);
}

cvReleaseMemStorage(&storage);
cvReleaseImage(&img);
cvReleaseImage(&gray);

]]>
</code>
</function>

</extension>

pecl-gen -f face_detect.xml
cd face_detect
phpize
./configure
make
make install

以上。簡単でしょ?

使い方は、
<?

$picture = "picture.jpg";
$cascade = "/usr/local/share/opencv/haarcascades/haarcascade_frontalface_alt.xml";

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

?>


※ソースの中身は、これで良いのか悪いのか、激しく不明。
特にCの部分とか、ライブラリの読み込みとか。
誰か、エロイ人教えて。



コメントの一覧
moriyoshi さん 3/14 13:07
エロい人ではありませんが、cvLoadImage() に失敗したときに Cascade を開放する処理を入れてみてはいかがでしょう?ささいなことですみません。

(さきほどトラックバックさせていただきました!)
ひろかわです さん 3/14 18:28
moriyoshiさん

こんにちは。なるほど、Cascadeを開放したほうが良いですね。
ちょっと調べて見ます。
ありがとうござます。
コメントはこちらから
名前:
通信:
※オーナーにのみ表示されます。(mail やホームページのurl等ご入力ください)
本文:
トラックバックはこちらから
トラックバックURL: