OpenCVで画像を作るにあたって,サンプルコードでは様々なクラス/構造体を使っている.その歴史も合わせてちょこちょこ書いてく

#contents

*IplImage [#ef2a07bd]
-オーソドックスな「画像」を保持する構造体
-OpenCV 1.1時代は盛んに使われていた.
-今でもCvMatやcv::Matなどと互換性はちゃんとある
-通常はポインタで宣言して,cvCreateImageで実体をallocする
-歴史
--IPLはもともとIntel IPP(Intel Integrated Performance Primitives)&note{IPP-en:[[Integrated Performance Primitives - Wikipedia>http://en.wikipedia.org/wiki/Integrated_Performance_Primitives]]};内の画像処理ライブラリ(Image Processing Library)&note{IPL-nekora:[[Intel Performance Libraly>http://homepage1.nifty.com/nekora/soft/howto/ipl.html]]};
--OpenCVの前身というと言い過ぎだけれど,もともとOpenCVはIntelの技術者たちが開発していた
--その名残りでIPLの名を冠する
-ヘッダとデータ部からなる
-ヘッダ部
--幅,高さ,チャンネル数,1画素のバイト数などの基本的な情報を保持する
--1画素のバイト数はIPL_DEPTH_8UやIPL_DEPTH_64Fなどで指定する
--IPP時代の名残で様々なメンバ変数が存続してるが,あまり使われてないのが現実
--メンバ変数の1つ,imageDataがデータ部を指すポインタになっている
-データ部
--unsigned char*型の配列
--ヘッダによれば,charの配列だが,これを信じると痛い目を見る(泣)
--ラスタスキャンで2次元画像が配列に保存されている
--なお,imageDataOriginはalloc時の番地を保持しているので,通常は
 imageData == imageDataOrigin
--であるが,imageDataポインタを別の番地に振り替えても,imageDataOriginが番地を保持しているのでメモリリークは起きない&note{dandelion-releaseimage:[[dandelion's log » cvReleaseImageの挙動について>http://www.atinfinity.info/blog/archives/99]]};

*CvMat [#ecc2cf03]
-オーソドックスな行列を保持する構造体
-IplImageと同様,ヘッダ部とデータ部からなる
-通常はポインタで宣言して,cvCreateMatで実体をallocする
-ヘッダ部
--幅,高さ,チャンネル数,1画素のバイト数などの基本的な情報を保持する
--1画素のバイトはCV_8UとかCV_32Fなどで指定する
--チャンネル数も同様にCV_8UC1とかCV_8UC3とかC?で指定する
--チャンネル数を省略した場合は1チャンネル(画像でいうところの濃淡画像)になる
--dataというunionのポインタがデータ部を指すポインタになっている
--IplImageと違い,配列はデータに応じてdoubleやfloatでもよい.
--data.ptr内の変数をそれぞれ使ってデータ部にアクセスする
-データ部
--ラスタスキャンで行列が配列に保存されている

*CvArr [#p7b1903d]
-実体はvoid
-関数の引数が大体の場合CvArr*になっていて,多分初心者は大体躓く.
-CvMatとIplImageを同列に扱うためにvoidのポインタで宣言されている
-これを引数として扱う関数は,内部で渡されたポインタが
--IplImageのポインタか
--CvMatのポインタか
-判断するようにできている

*cv::Mat [#i79efe6e]
-OpenCV 2.0から登場したC++版の画像クラス&note{MatIntroduce:[[Changeset 1611 - OpenCV>https://code.ros.org/trac/opencv/changeset/1611]]};
-C++版では画像も行列も一様に扱う
-クラスなので,大量のメンバ関数やoperatorが実装されている
-行列同士の掛け算や動的な配列再確保が実装されていて超便利
-個人的には,CvMatやIplImageなどの配列に戻る必要性を感じない
-キャストやcvarrToMatでIplImageやCvMatに変換できる
#geshi(c++,number){{
CvMat *oldMatrix  = cvCreateMat(3, 3, CV_32FC1);
cv::Mat matrix    = cv::cvarrToMat(oldMatrix);
CvMat _stub       = (CvMat)matrix;
CvMat *oldMatrix2 = &(_stub);
}}
-個人的には行列の演算を通常の四則演算の用に書けるのが嬉しい
#geshi(c++,number){{
cv::Mat A(3, 3, CV_32F);
cv::Mat B(3, 3, CV_32F);
cv::Mat C(3, 3, CV_32F);
C = A - B;
C = A + B;
C = A * B;
}}

*cv::InputArray [#fe1ffe4a]
-Revision 4885&note{proxyType:[[Changeset 4885 - OpenCV>https://code.ros.org/trac/opencv/changeset/4885]]}; から導入されたInputArray
-proxy type とChangeLogに書かれている
-OpenCV 2.3以降に相当する
-変換関数やキャストせずに,どんな配列も受け取る為の型
-Matはもちろん,Point,Point3やVecなどのデータも同じようにやり取りできる
-C++版の[[CvArr*>OpenCVの画像クラス/構造体#k5facf20]]に近い存在
-基本的にInputArrayはMat&と読み替えて構わない.
-以下がtypedef文(OpenCV 2.4.1)
#geshi(C++,number,start=1334){{
typedef const _InputArray& InputArray;
typedef InputArray InputArrayOfArrays;
typedef const _OutputArray& OutputArray;
typedef OutputArray OutputArrayOfArrays;
typedef OutputArray InputOutputArray;
typedef OutputArray InputOutputArrayOfArrays;
}}
-InputArrayとInputArrayOfArraysは _InputArray& で Mat&と読み替えられる
-OutputArrayとOutputArrayOfArraysとInputOutputArrayとInputOutputArrayOfArraysは _OutputArray& で Mat&と読み替えられる

ジャンル[[:OpenCV]][[:OpenCV 1.0]][[:OpenCV 1.1]][[:OpenCV 2.0]][[:OpenCV 2.1]][[:OpenCV 2.2]][[:OpenCV 2.3]][[:OpenCV 2.4]]準拠
&note{opencv-wikipedia:[[OpenCV - Wikipedia (日本語)>http://ja.wikipedia.org/wiki/OpenCV]]};
&note{opencv-wikipedia-en:[[OpenCV - Wikipedia (English)>http://en.wikipedia.org/wiki/OpenCV]]};

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS