名前
Cv - 何かコンピュータビジョンでやってみるとき、 あなたの助けになるように
概要
use Cv;
my $image = Cv->LoadImage("/path/to/image");
$image->ShowImage("image");
Cv->WaitKey;
説明
Cv
は OpenCV コンピュータビジョンライブラリの Perl インタフェースです。 OpenCV はインテルで生まれ、 その後、皆の手によって素敵なライブラリとして成長を続けています。 そこには C/C++ だけでなく Python のインタフェースもありますが、Perl もあって良いと思いました。 Perl のスローガンに則り、簡単なことは簡単に、難しいこともそれなりに。 Cv
の特徴は次のとおりです。
Cv
は、OpenCV の C言語のリファレンスに合わせて作成しました。 詳細は http://opencv.itseez.com/ を参照してください。コンストラクタとして
Createなんとか()
を使うことができます。my $img = Cv->CreateImage([ 320, 240 ], IPL_DEPTH_8U, 3); my $mat = Cv->CreateMat([ 240, 320 ], CV_8UC3);
コンストラクタに
new
を使うこともできます。 CreateImage() の代りにCv::Image->new
を、 CreateMat() の代りにCv::Mat->new
を使うことができます。 呼び出し形式について、 CreateImage() と CreateMat() は違いますが、Cv::something->new
を介した場合、違いはありません。 これは、Cv::Arr
の中で、元のオブジェクトのことを知らないで 同じオブジェクトを作れるようにしています。my $color = Cv::Image->new([ 240, 320 ], CV_8UC3);
引数は省略できます。省略したものは元のオブジェクトから引き継がれます。
my $img2 = $img->new; my $img3 = $img->new(CV_8UC1); # Cv::Image->new([240, 320], CV_8UC1)
OpenCV には画像を扱う型として
IplImage*
、 マトリクスを扱う型としてCvMat*
、CvMatND*
、CvSparseMat*
があります。Cv
ではこれらをCv::Image
、Cv::Mat
、Cv::MatND
、Cv::SparseMat
で bless したリファレンスで表わします。 それから、こうした画像やマトリクスを区別なく扱えるCv::Arr
があります。CvPoint
やCvSize
はメンバの値を並べた配列で表わします。 詳細は typemap を参照してください。OpenCV は
cvCreateImage()
で割り当てたメモリを開放するためにcvReleaseImage()
を使いますが、 Cv ではオブジェクトが消滅するときに呼ばれるDESTROY
の中で後始末をします。 そのためDESTROY
は、しばしばcvReleaseなんとか()
の別名として定義されています。cvQueryFrame()
のように開放できないポインタを返すものは、Cv::なんとか::Ghost
で bless して区別し、 オブジェクトの開放を抑止しています。メソッドの名前は、OpenCV の関数名の頭の
cv
を省いた名前と、 名前のはじめの大文字を小文字に直したものが使えます。 次の 2つの例はどちらもcvCreateMat()
を呼び出します。my $mat = Cv->CreateMat(240, 320, CV_8UC3); my $mat = Cv->createMat(240, 320, CV_8UC3);
出力先の画像やマトリクス (
dst
として表わされることが多い) が省略されたとき、 それが補える場合には補うようにしています。my $dst = $src->Add($src2);
OpenCV は、インプレース処理が可能な関数では出力先の画像やマトリクス
dst
にNULL
を指定し、入力画像を出力先として扱います。Cv
ではこのNULL
を表わすために\0
を使います。my $dst = $src->Flip(\0);
cvAdd()
とcvAddS()
のような類似した関数はAdd()
にまとめました。メソッドの名前を変えて扱うデータを区別する必要はありません。my $dst = $src->Add($src2); # cvAdd() を呼ぶ my $dst = $src->Add([ 1, 2, 3 ]); # cvAddS()
配列を扱う関数、たとえば
FillConvexPoly()
は点CvPoint
の配列を扱いますが、C言語は配列をその先頭のポインタで表すので、 別途、配列の大きさも渡さなければなりません。 Perl は配列の大きさも分るので、単に点の配列を渡すだけで十分です。CreateMatND()
やFindCornerSubPix()
等も同様です。cvMinMaxLoc() の類は与えられた変数に値を格納します。
$src->MinMaxLoc(my $min, my $max);
$min
と$max
を呼び出し元に返すには、 stat() や localtime() のように戻り値の方が使いやすいかもしれませんが、 OpenCV のリファレンスに合わせました。Inline C
を使うためのコンフィギュレーションを用意しました。 これは、いろいろな実験や拡張を容易にしてくれます。 使い方は次のとおり簡単です。use Cv::Config; use Inline C => Config => %Cv::Config::C;
ヒント
Cv を使っている方から、ちょっといい使い方を教えて戴きました。
Cv で作成した画像を CGI で直接出力するとき、 EncodeImage() と Ptr() を使うことができます。 画像をファイルに保存する必要がありません。
use Cv; my $img = Cv::Image->new([240, 320], CV_8UC3); $img->zero->circle([ 100, 100 ], 100, CV_RGB(255, 100, 100)); print "Content-type: image/jpg\n\n"; print $img->encodeImage(".jpg")->ptr;
これは Imager 向けの変換にも使えます。
use Imager; my $imager = Imager->new(data => $img->encodeImage(".ppm")->ptr);
Perl のデータに Cv のヘッダを付けることができます。 行儀が良いとは言えませんが、 Cv で Perl のデータを直接操作できるようになります。
my $data = pack("C*", 0 .. 255); my $mat = Cv::Mat->mew([16, 16], CV_8UC1, $data); substr($data, 0x41, 1) = 'x'; print chr($mat->get([4, 1])->[0]), "\n";
サンプル
OpenCV に付属しているサンプルを、いくつか Cv
で書き直しました。 sample/
にあります。
bgfg_codebook.pl calibration.pl camshiftdemo.pl capture.pl contours.pl
convexhull.pl delaunay.pl demhist.pl dft.pl distrans.pl drawing.pl
edge.pl facedetect.pl fback_c.pl ffilldemo.pl find_obj.pl
fitellipse.pl houghlines.pl image.pl inpaint.pl kalman.pl kmeans.pl
laplace.pl lkdemo.pl minarea.pl morphology.pl motempl.pl
mser_sample.pl polar_transforms.pl pyramid_segmentation.pl squares.pl
stereo_calib.pl stereo_match.pl tiehash.pl watershed.pl
バグ
進歩し続ける OpenCV の新しい機能が使いたくなったら、
Cv
のプロトタイプを xs に置いてください。 パッケージCv
またはCv::Arr
に配置できるときは、 名前の調整 (cv
を取り除いたり、はじめの大文字を小文字に直したり) はAUTOLOAD
が始末するため、橋渡しのコード以外に必要なものはありません。 それ以外のところでは、Cv::aliases
を使うことができます。新しい定数が使いたくなったら
Cv::Constant
に書かなければなりません。バージョン 0.07 で名前付きの引数を諦めました。 名前付きの引数には大きなオーバヘッドがあったからです。 この版では
Cv::TieHash
とCv::TieArr
も削除しました。Cv::TieHash
はsample/tiehash.pl
を参照してください。
参考
http://sourceforge.net/projects/opencvlibrary/
著作権
Yuta MASUDA <yuta.masuda@newdaysys.co.jp>
Copyright (c) 2010, 2011 by Yuta MASUDA.
All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.