波打際のブログさん

主に、プログラミング備忘録など。

PHP5.4でLibpuzzleを使って画像の類似度判定を行う

はじめに

 Libpuzzleとは特徴検出のアルゴリズムにより、高速な画像類似度判定を行うことができるライブラリです。しかし、このライブラリをPHP5.4で利用しようとした場合、エクステンションがPHP5.4からロードされた瞬間にセグメンテーション違反(segmentation fault)が発生し強制終了させられます。

 調査した結果、原因はPHP用のエクステンションのメモリ確保方法に問題があると判断しました。そこで、PHP5.4に対応したエクステンションの開発を行いました。今回はそのエクステンションの導入と簡単な動作確認用のPHPプログラムを作成します。

 また、この組み合わせで本家のPHPエクステンションがエラーを履かない場合は、本家を利用したほうが良いと思います。

環境

  • CentOS6.4
  • apache2.4.4
  • PHP5.4.16

Libpuzzleの導入

 PHP用のエクステンション導入の前にLibpuzzleを導入します。

GD2のインストール

 LibpuzzleはGD2を利用して類似度判定を行うので、yumを利用してインストールします。

$ sudo yum install gd gd-devel

Libpuzzleのインストール

 GD2のインストールが終わったら次はLibpuzzle本体をインストールします。本体は本家サイト(Libpuzzle - A library to find similar pictures)からダウンロードします。

$ wget http://download.pureftpd.org/pub/pure-ftpd/misc/libpuzzle/releases/libpuzzle-0.11.tar.bz2
$ tar -jxvf libpuzzle-0.11.tar.bz2

Libpuzzle-0.11 $ ./configure
Libpuzzle-0.11 $ make clean
Libpuzzle-0.11 $ make
Libpuzzle-0.11 $ sudo make install

PHP用エクステンションのインストール

 本来ならば、libpuzzle-0.11.tar.bz2に同梱されている php/Libpuzzle を利用しますが、冒頭で述べたようにPHP5.4でsegfaultを吐いてしまったので、PHP5.4用に開発を行ったphp-libpuzzle5(alfa-jpn/php-libpuzzle5 · GitHub)を利用します。

php-libpuzzle5のインストール

 git-hubのreleaseからバージョン1.0.0をダウンロードしてインストールします。

$ wget https://github.com/alfa-jpn/php-libpuzzle5/archive/1.0.0.tar.gz
$ tar -zxvf php-libpuzzle5-1.0.0.tar.gz

php-libpuzzle5-1.0.0 $ phpize
php-libpuzzle5-1.0.0 $ ./configure
php-libpuzzle5-1.0.0 $ make clean
php-libpuzzle5-1.0.0 $ make
php-libpuzzle5-1.0.0 $ sudo make install

php.iniの設定

 PHPの設定ファイル(/usr/local/lib/php.ini)にエクステンションを読み込む設定を追記します。

extension=libpuzzle5.so

以上でインストール作業は完了です。

テストプログラムを書いてみる

 こんな感じでプログラムを記述します。 $dは0〜1の間の値で、0に近いほど画像が似ていると判定されています。

<?php

$cvec1 = puzzle_fill_cvec_from_file(dirname(__FILE__) . '0.jpg');
$cvec2 = puzzle_fill_cvec_from_file(dirname(__FILE__) . '1.jpg');
$d = puzzle_vector_normalized_distance($cvec1, $cvec2);
echo '類似度は' . $d . 'です。';

?>

 puzzle_fill_cvec_from_fileの引数を絶対パスで指定している点に注意して下さい。PHPから呼び出せる関数は本家のlibpuzzleエクステンションと同様ですので、本家のドキュメントを参照してください。