The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

名前

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 を使うこともできます。 しかし引数は CreateMat() に揃えたので少し違います。注意してください。

     my $img = Cv::Image->new([ 240, 320 ], CV_8UC3);
     my $img2 = $img->new;
  • OpenCV には画像を扱う型として IplImage*、 マトリクスを扱う型として CvMat*CvMatND*CvSparseMat* があります。 Cv ではこれらを Cv::ImageCv::MatCv::MatNDCv::SparseMat で bless したリファレンスで表わします。 それから、こうした画像やマトリクスを区別なく扱える Cv::Arr があります。 CvPointCvSize はメンバの値を並べた配列で表わします。 詳細は 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 は、インプレース処理が可能な関数では出力先の画像やマトリクス dstNULL を指定し、入力画像を出力先として扱います。 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()

    cvGet1D()cvGet2D() も同様に

     my $val = $src->Get($idx1);        # cvGet1D()
     my $val = $src->Get($idx1, $idx2); # cvGet2D()
  • 配列を扱う関数、たとえば 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;

サンプル

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 tiehash.pl watershed.pl

バグ

  • 進歩し続ける OpenCV の新しい機能が使いたくなったら、Cv のプロトタイプを xs に置いてください。 パッケージ Cv または Cv::Arr に配置できるときは、 名前の調整 (cv を取り除いたり、はじめの大文字を小文字に直したり) は AUTOLOAD が始末するため、橋渡しのコード以外に必要なものはありません。 それ以外のところでは、Cv::aliases を使うことができます。

  • 新しい定数が使いたくなったら Cv::Constant に書かなければなりません。

  • バージョン 0.07 で名前付きの引数を諦めました。 名前付きの引数には大きなオーバヘッドがあったからです。 この版では Cv::TieHashCv::TieArr も削除しました。 Cv::TieHashsample/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.