Thriftを利用してOpenCVの関数をスクリプトから呼んでみます。
といってもRPCで繋げるだけで特別なことをする必要はありません。
ここでは、画像の各チャンネルの平均値と標準偏差を求めてみます。
サーバ側でOpenCVの cvAvgSvd() を利用すればOK。
まず、最初にRPCのインタフェースをThrift IDLに書きます。
ここでは、平均と標準偏差を求める関数を2つ作ることにしました。
各チャンネルの値が欲しいので戻り値は list<double> に、
引数は画像ファイル名を指定したいので string にしておきます。
* cv.thrift (サービス名は CV)
service CV {
list<double> calcAvg(1: string img)
list<double> calcSdv(1: string img)
}
* thriftコマンドでコード生成
$ thrift --gen cpp --gen perl --gen php --gen rb cv.thrift
サーバ側の実装ではC++で普通にOpenCVを使って書けばOKです。
(今回の場合は gen-cpp/CV_server.skeleton.cpp というファイルを編集する)
メソッドの引数にだけ注意しておきます。
ここではコードを一部省略しますが、実際はドメインロジック以外自動生成されます。
ソケットを作って接続を待ったり、データ構造をシリアライズしたりといった面倒な部分は、
全てThriftが引き受けてくれるので安心です。
* サーバ側 CV_server.skeleton.cpp (C++) #include /* 中略 */ class CVHandler : virtual public CVIf { void calcAvg(std::vector * コンパイル 次はクライアント側を実装します。 use strict; use Thrift; use CV; my $transport = Thrift::Socket->new(‘localhost’, 9090); eval { if($@) { 上手くいきました。 [php] ?> * 出力結果 詳細は省きますが、Rubyでもシンタックスを変えるだけで利用できます。 今回はThriftを使って各言語から簡単にOpenCVを利用できることを確認しました。 それはともかくOpenCV 2.0 のリリースが Sept. 31, 2009 って書いてありましたが、
[csharp]
#include “CV.h”
#include
#include
#include
#include
IplImage *srcImg;
CvScalar mean;
CvScalar std_dev;
public:
CVHandler() {
srcImg = 0;
mean = cvScalarAll(0);
std_dev = cvScalarAll(0);
}
if((srcImg = cvLoadImage(img.c_str(), CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR)) == 0) {
std::cout<<"load error."<
/* 以下略 (calcAvgと同様に書けばよい)*/
[/csharp]
$ g++ -g CV.cpp CV_server.skeleton.cpp -o CV_server `pkg-config --cflags --libs opencv thrift`
* クライアント側 cv.pl (Perl)
[php]
#!/usr/bin/perl
use warnings;
use lib ‘./gen-perl’;
use Thrift::BinaryProtocol;
use Thrift::Socket;
my $client = CVClient->new(Thrift::BinaryProtocol->new($transport));
$transport->open();
print “Calculate the Mean\n( Blue Green Red ) = ( “;
printf “%f “, $_ for @{$client->calcAvg(“lena.jpg”)}; # 戻り値はリストリファレンス
print “)\n\n”;
print “Calculate the Standard-Deviation\n( Blue Green Red ) = ( “;
printf “%f “, $_ for @{$client->calcSdv(“baboon.jpg”)};
print “)”;
$transport->close();
};
warn $@->{message};
}
[/php]
* サーバの起動およびクライアントの実行
$ mv ./gen-cpp/CV_server .
$ ./CV_server
$ chmod +x cv.pl
$ ./cv.pl
Calculate the Mean
( Blue Green Red ) = ( 105.398991 99.562698 179.730305 )
Calculate the Standard-Deviation
( Blue Green Red ) = ( 60.611124 47.493925 55.499225 )
次はPHPから。抽象化レイヤのおかげでPHPでも簡単に使えます。
* クライアント側 cv.php (PHP)
open();
print_r($client->calcAvg(“lena.jpg”)); /* Perl版と同じように呼べる */
print_r($client->calcSdv(“baboon.jpg”));
$transport->close();
}catch(Exception $e) {
echo $e->getMessage();
}
[/php]
Array
(
[0] => 105.3989906311
[1] => 99.562698364258
[2] => 179.73030471802
)
Array
(
[0] => 60.611123950567
[1] => 47.493925313866
[2] => 55.499224912776
)
[php]
# Rubyでも簡単
client.calcAvg(“lena.jpg”)
client.calcSdv(“baboon.jpg”)
[/php]
また便利な機能が追加されてるんですかね。楽しみです。あわせて読む: