MASUDA Yuta > Cv-0.21 > lib/Cv-ja.pod

Download:
Cv-0.21.tar.gz

Annotate this POD

CPAN RT

New  6
Open  0
View/Report Bugs
Source  

名前 ^

Cv - 何かコンピュータビジョンでやってみるとき、あなたの助けになるように (只今、書き直し中)

概要 ^

 use Cv;
 
 my $image = Cv->LoadImage("/path/to/image");
 $image->ShowImage("image");
 Cv->WaitKey;
 
 my $capture = Cv->CaptureFromCAM(0);
 while (my $frame = $capture->QueryFrame) {
   $frame->Flip(\0, 1)->ShowImage;
   my $c = Cv->WaitKey(100);
   last if $c >= 0;
 }

説明 ^

Cv は OpenCV コンピュータビジョンライブラリの Perl インタフェースで す。OpenCV の C言語のリファレンスを元にしたので、リファレンスとして http://opencv.willowgarage.com/ が使えます。とは言え、異なる部分もあり、 少しずつ文書にまとめています。

中途半端で申し訳ありません。

コンピュータビジョンは少し難しいので、Perl のスローガンに則り「簡単なこ とは簡単に、難しいこともそれなりに」を心掛けています。

オブジェクト

オブジェクトの作成と解放

OpenCV の画像やマトリクスのオブジェクトは、C言語と同様に Createなんとか() で作ります。

 my $img = Cv->CreateImage([ 320, 240 ], IPL_DEPTH_8U, 3);
 my $mat = Cv->CreateMat(240, 320, CV_8UC4);

オブジェクトは new で作ることもできます。画像を作る CreateImage() と マトリクスを作る CreateMat() は、上の例のとおり呼び出し形式が違いますが。 new なら同じように作ることができます。

 my $arr = Cv::Image->new($size, $type);
 my $arr = Cv::Mat->new($size, $type);
 my $arr = Cv::MatND->new($size, $type);
 my $arr = Cv::SparseMat->new($size, $type);

またオブジェクトを作るとき、元のオブジェクトがあれば引数を省略すること もできます。

 my $sameone = $img->new;
 my $gray = $color->new(CV_8UC1);

オブジェクトが不要になったら、C言語では Createなんとか() と対の Releaseなんとか() で利用者がオブジェクトを解放します。Perl は同じ場 面で DESTROY を呼ぶので、Cv はこの仕組みを使ってオブジェクトを解 放します。従って解放について利用者が注意を払う必要はありません。解放で きないオブジェクトは Cv::なんとか::Ghost というクラスで bless し、 Cv の中で識別できるようにしています。

OpenCVのデータ型とCvのクラス名

OpenCV には画像やマトリクスのデータ型として CvImage, CvMat, CvMatND, CvSparseMat など、いろいろな型があります。Cv は、この データ型とクラス名が対応しています。クラス名は、Cv の後に :: を置い た名前で、たとえば、CvImageCv::Image に、CvMatCv::Mat に対応しています。そして、オブジェクトは、OpenCV のデータの ポインタをそのデータ型に対応するクラス名で bless したものになります。

OpenCV の画像やマトリクスのデータ型 CvMatCvImage は、CvArr から導出されたデータ型です。従って、画像やマトリクスは CvArr を介し て受け渡されます。Cv でも同様に、スーパクラスとして Cv::Arr を用 意し、メソッドはできるだけここに置くことにしました。

OpenCV には更にシーケンスと呼ばれる動的なデータ型もありますが、これにつ いては、Cv::Seq を参照してください。

データ領域の共有

OpenCV の画像やマトリクスは、ヘッダ部とデータ部が分れており、データ部の ないヘッダだけのオブジェクトが作れます。データのないことを伝えるために、 次のとおり undef を渡します。

 my $arr = Cv::Mat->new([$rows, $cols], $type, undef);

このようにして作成したヘッダだけのオブジェクトは、GetRows(), GetCols() のようにデータ部を共有するメソッドで使っています。

(注意) コードを見ると、undef の代りに文字列でデータ部を与えることが可能 だと気付くかもしれません。別のシステムで作成した画像やマトリクスを扱う とき、データ変換の手間を減らすことができると考える人もいると思います。 しかし、オブジェクトが開放されるとき Cv::Image ではエラーが起きます。 Cv::Mat はなんとなく動いているように見えますが、安定していません。文字 列でデータ部を渡さないようにしてください。(これは bugs へ)

OpenCVの構造体

Cv のオブジェクトは、OpenCV の構造体をその型名に対応するクラス名で bless したものです。従って、Cv (Perl) から OpenCV の構造体は直接操作で きません。しかし、OpenCV に同梱されているサンプルでは、構造体の大きさや 要素の型を直接使っています。たぶんそれが簡単なんでしょう。Cv でも同様の 使い方をするために、構造体のメンバの名前でメソッドを作りました。詳細は "Cvで追加されたメソッド" を参照してください。

メソッド

メソッドの名前とその統合

メソッドの名前は、OpenCV の関数名の頭の cv を省いた名前と、名前のは じめの大文字を小文字に直したものが使えます。次の 2つの例はどちらも cvCreateMat() を呼び出します。

 my $mat = Cv->CreateMat(240, 320, CV_8UC3);
 my $mat = Cv->createMat(240, 320, CV_8UC3);

それから cvAdd()cvAddS() のような類似した関数はより簡潔な名前、 つまりこの例では Add() にまとめました。おそらく C言語では異なる型の 引数を受けとることができないので、分けるしかなかったのでしょう。Cv ではこれらを統合し、引数で呼び出す関数を決めています。

 my $ar2 = Cv->CreateImage();      # ref Cv::Image
 my $sc2 = cvScalar();             # ref ARRAY
 my $d = $ar->Add($ar2);           # cvAdd($ar, $ar2)
 my $d = $ar->Add($sc2);           # cvAddS($ar, $sc2)

統合した関数は次のとおり。あまり多くありません。リファレンスを参照して、 cvなんとか()cvなんとかS() の両方あるものがそうだと考えてください。

 AbsDiff(), Add(), And(), Cmp(), InRange(), Max(), Min(), Or(), Sub(), Xor()

引数の省略、インプレース、戻り値

出力先の画像やマトリクス (dst として表わされることが多い) が省略され たとき、それが補える場合は補うようにしています。補える例とそうでない例の 両方を示します。

 my $dst = $src->Add($src2);
 my $dst = $src->Add($src2, $mask);  # can't omit dst

後者は、マスクとして与えた $mask と出力先を区別することができません。 このような場合には $dst を呼び出し元で用意してください。$dst$src と同じなら次のとおり。

 my $dst = $src->Add($src2, $src->new, $mask); 

OpenCV は、インプレース処理が可能な関数では出力先の画像やマトリクス dstNULL を指定し、入力画像を出力先としても使います。Cv で はこの NULL を表わすために \0 を使います。次の例は左右反転した画 像を返します。

 my $dst = $src->Flip(\0);

OpenCV の関数は、この Flip() に限らず、出力先は呼び出し元が用意します。 そうした使い方では特に戻り値を使う必要はありません。しかし、上述のとお り Cv では出力先を省略できるので、その場合にはメソッドの中で必要に応 じて作られた出力先を戻り値として受けとることになります。

この出力を戻り値として受けとる方法は、次の例のとおり、メソッドをつない で書けるようにしてくれますが、メソッドが呼ばれる度にオブジェクトの確保 と開放があるので、その分だけオーバヘッドがあります。

 my $bin = $src->cvtColor(CV_RGB2GRAY)->threshold(...);

Cvで追加されたメソッド

(これはプログラムで生成したい。書くのは疲れる)

エラー処理

eval { ... } で保護したブロックの中のエラーを検出できるようになりました。 (Cv-0.13)

 my $img = eval { Cv->createImage([-1, -1], 8, 3) };
 if ($@) {
    print STDERR "*** got error ***";
 }

ただし、Cv をインストールするとき、c++ でコンパイルしておく必要があります。 エラーを掴まえるだけでなく、自前で用意したエラー処理に向けることもできます。

 Cv->redirectError(
   sub { my ($status, $funcName, $errMsg, $fileName, $line, $data) = @_;
       ...
   },
   my $data = ...;
 );

エクスポート

Cv によってインポートされる名前は、use Cv の後に指定できます。(Cv-0.14)

次の 2行は、CVIPL ではじまる定数やマクロと cvScalarAll() のようないくつかの関数をインポートします。

 use Cv qw(:std);
 use Cv;                        # 何も指定しないとき :std が補われる

次の 2行は、Cv のすべての名前をインポートします。

 use Cv qw(:all);
 use Cv qw(/^(CV|IPL|cv)/);

何もインポートしないときは、空のリストを続けます。

 use Cv qw( );

ヒント ^

Cv を使っている方から、ちょっといい使い方を教えて戴きました。

サンプル ^

OpenCV に付属しているサンプルを、いくつか Cv で書き直しました。 sample/ にあります。

バグ ^

参考 ^

http://sourceforge.net/projects/opencvlibrary/

著作権 ^

Yuta MASUDA <yuta.masuda@newdaysys.co.jp>

Copyright (c) 2010, 2011, 2012 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.

syntax highlighting: