CV リファレンス マニュアル
-
画像処理(Image Processing)
- 勾配,エッジ,コーナー,特徴(Gradients, Edges, Corners and Features)
- サンプリング,補間,幾何変換(Sampling, Interpolation and Geometrical Transforms)
- モルフォロジー演算(Morphological Operations)
- フィルタと色変換(Filters and Color Conversion)
- ピラミッドとその応用(Pyramids and the Applications)
- 画像分割,領域結合,輪郭検出(Image Segmentation, Connected Components and Contour Retrieval)
- 画像と形状のモーメント(Image and Contour Moments)
- 特殊な画像変換(Special Image Transforms)
- ヒストグラム(Histograms)
- マッチング(Matching)
- 構造解析(Structural Analysis)
- モーション解析と物体追跡(Motion Analysis and Object Tracking)
- パターン認識(Pattern Recognition)
- カメラキャリブレーションと3次元再構成(Camera Calibration and 3D Reconstruction)
- (ピンホールカメラモデル, 歪み(Pinhole Camera Model, Distortion))
- シングルおよびステレオカメラキャリブレーション(Single and Stereo Camera Calibration)
- 姿勢推定(Pose Estimation)
- エピポーラ幾何,ステレオマッチング(Epipolar Geometry, Stereo Correspondence)
- 参考文献
カメラキャリブレーションと3次元再構成(Camera Calibration and 3D Reconstruction)
エピポーラ幾何(Epipolar Geometry)
FindFundamentalMat
2枚の画像間の点対応から基礎行列(F行列)を計算する
int cvFindFundamentalMat( const CvMat* points1,
const CvMat* points2,
CvMat* fundamental_matrix,
int method=CV_FM_RANSAC,
double param1=3.,
double param2=0.99,
CvMat* status=NULL);
- points1
- 大きさが2xN, Nx2, 3xN,また は Nx3 の1枚目の画像上の点の配列 (N は点の数). マルチチャンネルで大きさ 1xN,または Nx1 の配 列も使用可能である. 点の座標は浮動小数点型で表される(単精度または倍精度).
- points2
- 2枚目の画像上の点の配列で point1とフォーマッ トやサイズは同じ.
- fundamental_matrix
- 出力される基礎行列.サイズは 3x3, または 9x3(7-point methodは3つの行列を返す).
- method
- 基礎行列の計算手法.
- CV_FM_7POINT - 7-pointアルゴリズム. N == 7
- CV_FM_8POINT - 8-pointアルゴリズム. N > 8
- CV_FM_RANSAC - RANSAC アルゴリズム. N > 8
- CV_FM_LMEDS - LMedSアルゴリズム. N >= 8
- CV_FM_7POINT - 7-pointアルゴリズム. N == 7
- param1
- RANSAC メソッドのときにのみ使用されるパラメー タ.点からエピポーラ線までの最大距離(その距離を超えるもの は外れ値であると判断し,それらを最終的な基礎行列の計算に使 用しない)をピクセル単位で示す. 通常は 1〜3 の値にセットされる.
- param2
- RANSAC または LMedSメソッドのときにのみ使用されるパラメータ. F行列の推定精度の信頼レベルを示す.
- status
- オプション:N個の要素からなる出力配列. 各要素は,アウトライア(外れ値)に対しては 0, 「インライア」,つまり推定されたエピポーラ幾何に良く適合する値, に対しては 1 にセットされる. この配列は RANSAC または LMedS メソッドのときのみ計算される.他の手法では,すべて 1 にセットされる.
エピポーラ幾何は以下の式で表される.
p2T*F*p1=0,
ここで F は基礎行列,p1 と p2 は2枚の画像間での対応点である.
関数 cvFindFundamentalMat は,基礎行列を上記の4つの手法の うちの1つを用いて計算し,求めた基礎行列の数(1 または 3)を返す.もし行列が求まらないときは0を返す.
計算された基礎行列は,この後cvComputeCorrespondEpilinesに渡され,指定された点に対応するエピポーラ線を求める.
(例)RANSACアルゴリズムを用いた基礎行列の推定
int point_count = 100; CvMat* points1; CvMat* points2; CvMat* status; CvMat* fundamental_matrix; points1 = cvCreateMat(1,point_count,CV_32FC2); points2 = cvCreateMat(1,point_count,CV_32FC2); status = cvCreateMat(1,point_count,CV_8UC1); /* 点対応を与える */ for( i = 0; i < point_count; i++ ) { points1->data.db[i*2] = <x1,i>; points1->data.db[i*2+1] = <y1,i>; points2->data.db[i*2] = <x2,i>; points2->data.db[i*2+1] = <y2,i>; } fundamental_matrix = cvCreateMat(3,3,CV_32FC1); int fm_count = cvFindFundamentalMat( points1,points2,fundamental_matrix, CV_FM_RANSAC,3,0.99,status );
ComputeCorrespondEpilines
ステレオ画像の一方の画像上の点に対応する他方の画像上の エピポーラ線を計算する
void cvComputeCorrespondEpilines( const CvMat* points,
int which_image,
const CvMat* fundamental_matrix,
CvMat* correspondent_lines);
- points
- 入力点で大きさは2xN, Nx2, 3xN,また はNx3の配列である (ここで N は 点の数). マルチチャンネルの 1xN,また は Nx1 の配列も使用可能.
- which_image
- pointsを含む画像のインデックス(1 または 2).
- fundamental_matrix
- 基礎行列.
- correspondent_lines
- 計算されたエピポーラ線.大きさ は3xN また Nx3 の配列.
関数 cvComputeCorrespondEpilines は,ステレオ画像の一方の 画像上の各点に対応する他方の画像上の点(つまり,同じ3次元点を投影したもの) を含むような直線の方程式を求める. それぞれの線は,以下に示すように3つの要素 l=[a,b,c]T を持つベクトルで表される.
lT*[x, y, 1]T=0, または a*x + b*y + c = 0基礎行列の定義から (cvFindFundamentalMat を 参照),1枚目の画像(which_image=1)上の 点p1に対応する直線l2は 以下のように計算される.
l2=F*p1また,2枚目の画像(which_image=2)上の 点p2に対応する直線l1は 以下のように計算される.
l1=FT*p2
直線の係数はある範囲内に収まる.この直線は (a2+b2=1)となるように正規化され, correspondent_lines として保存される.
ConvertPointsHomogeneous
座標を同次座標に(または,同次座標から座標)変換する
void cvConvertPointsHomogeneous( const CvMat* src, CvMat* dst );
- src
- 入力点の配列.大きさは2xN, Nx2, 3xN, Nx3, 4xN, またはNx4(ここでNは点の数).マルチチャンネ ルの1xNまたはNx1の配列も使用可能.
- dst
- 出力点の配列.入力配列と同じ数の点が含まれる次元数は,同じ, あるいは入力より1少ないか1大きい.そして2..4の範囲内でなければならない.
関数 cvConvertPointsHomogeneous は,2次元または3次元の点を 同次座標に(または,同次座標から座標に)変換,単純なコピー,あるいは配列の転置を行う. もし入力配列の次元が出力配列より大きい場合,各座標値はベクトルの最後の座標値(要素値)で割られる.
(x,y[,z],w) -> (x',y'[,z']): x' = x/w y' = y/w z' = z/w (出力が3次元の場合)出力配列の次元が大きい場合は,それぞれの点座標ベクトルに1が加えられる.
(x,y[,z]) -> (x,y[,z],1)これ以外の場合は,入力配列が単純に出力にコピー(オプションとして転置を伴う)される. 注釈:この関数はさまざまな種類の配列を受け付けるので, 入力と出力の次元が不明瞭であるときはエラーを報告する場合がある. この関数を入力点数 N>=5 で使用するか, マルチチャンネルの Nx1 または 1xN の配列を用いれば,常に安全 である.
CvStereoBMState
ブロックマッチングによるステレオマッチングアルゴリズムのための構造体
typedef struct CvStereoBMState { // 事前フィルタ(入力画像の正規化): int preFilterType; // 0(現在のところ) int preFilterSize; // おおよそ 5x5 から 21x21 int preFilterCap; // おおよそ 31 以下 // SAD(Sum of Absolute Difference)によるマッチング int SADWindowSize; // 5x5 から 21x21 int minDisparity; // 最小視差(=0) int numberOfDisparities; // 最大視差-最小視差 // 事後フィルタ(悪いマッチング結果を破棄): int textureThreshold; // テクスチャのない領域は無視される float uniquenessRatio;// 異なる視差でのマッチが近辺にある場合, // そのピクセルは除外される. int speckleWindowSize;// 視差変化ウィンドウ(利用されない) int speckleRange; // ウィンドウの変化範囲(利用されない) // 内部バッファ.変更しないこと!! CvMat* preFilteredImg0; CvMat* preFilteredImg1; CvMat* slidingSumBuf; } CvStereoBMState;
Kurt Konolige による ブロックマッチングによるステレオマッチングアルゴリズムは, 非常に高速な 1-パス ステレオマッチングアルゴリズムである. これは,左右の画像において比較するピクセル位置のずれを変化 (minDisparity から minDisparity+numberOfDisparities まで) させながら,輝度値の差の絶対値の総和を画像全体に渡って計算する. このアルゴリズムは,WxH の画像のペアにおいて,その視差を O(W*H*numberOfDisparities) 回計算する. このアルゴリズムは,視差画像の質と信頼性を向上させるために, 事前フィルタおよび事後フィルタを導入している.
このアルゴリズムは,対応するブロックを,x-軸方向にのみ探索する事に注意する. つまり,平行化されているステレオ画像ペアに適応するべきである. また,垂直ステレオは直接サポートされていないが,そのような場合,ユーザは画像を転置させればよい.
CreateStereoBMState
ステレオブロックマッチング構造体を作成する
#define CV_STEREO_BM_BASIC 0
#define CV_STEREO_BM_FISH_EYE 1
#define CV_STEREO_BM_NARROW 2
CvStereoBMState* cvCreateStereoBMState( int preset=CV_STEREO_BM_BASIC,
int numberOfDisparities=0 );
- preset
- あらかじめ定義されたパラメータのID.構造体を作成した後で,任意のパラメータをオーバーライドできる.
- numberOfDisparities
- 視差数(最大視差-最小視差). このパラメータが 0 の場合,preset から選択される. そうでない場合は,与えられた値が preset の値をオーバーライドする.
関数 cvCreateStereoBMState は, ステレオマッチング構造体を作成し,それを初期化する. cvFindStereoCorrespondenceBM を呼ぶまでは,いつでも任意のパラメータをオーバーライドする事ができる.
ReleaseStereoBMState
ステレオブロックマッチング構造体を解放する
void cvReleaseStereoBMState( CvStereoBMState** state );
- state
- 解放される構造体へのポインタのポインタ
関数 cvReleaseStereoBMState は, ステレオマッチング構造体と,関連するすべての内部バッファを解放する.
FindStereoCorrespondenceBM
ブロックマッチングアルゴリズムを用いて視差画像を計算する
void cvFindStereoCorrespondenceBM( const CvArr* left, const CvArr* right,
CvArr* disparity, CvStereoBMState* state );
- left
- 左画像.シングルチャンネル,8ビット.
- right
- 右画像.左画像と同じサイズ,同じ種類.
- disparity
- 出力の視差配列.シングルチャンネル,16ビット,符号有り整数,入力画像と同サイズ. 各要素は,計算された視差であり,16倍されて整数値にまるめられる.
- state
- ステレオマッチング構造体.
関数 cvFindStereoCorrespondenceBM は, 平行化された入力ステレオ画像ペアの視差画像を計算する.
CvStereoGCState
グラフカットに基づくステレオマッチングのための構造体
typedef struct CvStereoGCState { int Ithreshold; // データ項の閾値(デフォルトでは 5) int interactionRadius; // 平滑化項の範囲(デフォルトでは 1,Pottsモデル) float K, lambda, lambda1, lambda2; // コスト関数のパラメータ // (通常は,入力データから適応的に求められる) int occlusionCost; // デフォルトでは 10000 int minDisparity; // デフォルトでは 0.CvStereoBMState を参照 int numberOfDisparities; // ユーザによって定義される.CvStereoBMState を参照 int maxIters; // 繰り返し計算の回数.ユーザによって定義される // 内部バッファ CvMat* left; CvMat* right; CvMat* dispLeft; CvMat* dispRight; CvMat* ptrLeft; CvMat* ptrRight; CvMat* vtxBuf; CvMat* edgeBuf; } CvStereoGCState;
[Kolmogorov03] で紹介されたグラフカットステレオマッチングアルゴリズム(KZ1 として知られている)は, 非リアルタイムのステレオマッチングアルゴリズムであり,通常, 明確なオブジェクト境界を示す非常に正確な奥行き画像を計算する. このアルゴリズムは,ステレオ問題を2値最適化問題のシーケンスとして扱い, それぞれは最大流アルゴリズム(max flow algorithm)を用いて解かれる. 上述の構造体は,手動で確保,初期化されるべきではない. その代わりに, cvCreateStereoGCState を利用して,必要ならばパラメータをオーバーライドする.
CreateStereoGCState
グラフカットステレオマッチングアルゴリズムの構造体を作成する
CvStereoGCState* cvCreateStereoGCState( int numberOfDisparities,
int maxIters );
- numberOfDisparities
- 視差数.視差の探索範囲は, state->minDisparity ≤ disparity < state->minDisparity + state->numberOfDisparities となる.
- maxIters
- 繰り返し計算の最大数. 各繰り返しにおいて,すべての(あるいは,適度な数の)α拡張を行う. このアルゴリズムは,コスト関数全体を減少させるα拡張が見つからなかった場合は, そこで終了する.詳しくは,[Kolmogorov03] を参照すること.
関数 cvCreateStereoGCState は, ステレオマッチング構造体を作成し,それを初期化する. cvFindStereoCorrespondenceGC を呼ぶまでは,いつでも任意のパラメータをオーバーライドする事ができる.
ReleaseStereoGCState
グラフカットアルゴリズムに基づくステレオマッチング構造体を解放する
void cvReleaseStereoGCState( CvStereoGCState** state );
- state
- 解放される構造体へのポインタのポインタ
関数 cvReleaseStereoGCState は, ステレオマッチング構造体と,それに関連するすべての内部バッファを解放する.
FindStereoCorrespondenceGC
グラフカットに基づくアルゴリズムにより視差画像を計算する
void cvFindStereoCorrespondenceGC( const CvArr* left, const CvArr* right,
CvArr* dispLeft, CvArr* dispRight,
CvStereoGCState* state,
int useDisparityGuess CV_DEFAULT(0) );
- left
- 左画像.シングルチャンネル,8ビット.
- right
- 右画像.左画像と同じサイズ,同じ種類.
- dispLeft
- 出力オプション:シングルチャンネル,16ビット,符号有り整数.入力画像と同じサイズの左視差画像.
- dispRight
- 出力オプション:シングルチャンネル,16ビット,符号有り整数.入力画像と同じサイズの右視差画像.
- state
- ステレオマッチング構造体.
- useDisparityGuess
- このパラメータが 0 でない場合, あらかじめ定義された視差画像を用いて計算が開始される.つまり, dispLeft と dispRight が共に,妥当な視差画像である必要がある. そうでない場合は,(すべてのピクセルがオクルージョンとなっている)空の視差画像から開始される.
関数 cvFindStereoCorrespondenceGC は, 平行化された入力ステレオ画像ペアの視差画像を計算する. 左視差画像は,以下の範囲の値を含むことに注意する:
-state->numberOfDisparities-state->minDisparity < dispLeft(x,y) ≤ -state->minDisparity, あるいは dispLeft(x,y) == CV_STEREO_GC_OCCLUSION,また,右視差画像は以下のようになる:
state->minDisparity ≤ dispRight(x,y) < state->minDisparity+state->numberOfDisparities, あるいは dispRight(x,y) == CV_STEREO_GC_OCCLUSION,つまり,右視差画像では,左視差画像と範囲が逆転している. マッチング結果が良くないピクセルは,オクルージョンとして処理される.
次に,この関数の使い方を示す:
// image_left と image_right はそれぞれ,左右のカメラの // 8 ビット,シングルチャンネルの入力画像 CvSize size = cvGetSize(image_left); CvMat* disparity_left = cvCreateMat( size.height, size.width, CV_16S ); CvMat* disparity_right = cvCreateMat( size.height, size.width, CV_16S ); CvStereoGCState* state = cvCreateStereoGCState( 16, 2 ); cvFindStereoCorrespondenceGC( image_left, image_right, disparity_left, disparity_right, state, 0 ); cvReleaseStereoGCState( &state ); // 計算された視差画像を使って,以下で好きな処理を行う…以下は,有名な Tsukuba ステレオペア画像から計算された出力左視差画像を, -16 倍したものである(通常,左視差画像は負の値を持つので):
CvMat* disparity_left_visual = cvCreateMat( size.height, size.width, CV_8U ); cvConvertScale( disparity_left, disparity_left_visual, -16 ); cvSave( "disparity.png", disparity_left_visual );
ReprojectImageTo3D
視差画像を三次元空間に再投影する
void cvReprojectImageTo3D( const CvArr* disparity,
CvArr* _3dImage, const CvMat* Q );
- disparity
- 視差画像.
- _3dImage
- 3 チャンネル,16ビット あるいは 32ビットの浮動小数点型画像. - 出力は,三次元点の集合になる.
- Q
- 4×4 の再投影行列.
関数 cvReprojectImageTo3D は, シングルチャンネルの視差画像を,三次元面である3チャンネルの画像に変換する. つまり,各ピクセル (x,y) と,それに対応する視差 d=disparity(x,y) が与えられると,以下のように変換される:
[X Y Z W]T = Q*[x y d 1]T _3dImage(x,y) = (X/W, Y/W, Z/W)
行列 Q は, 例えば,cvStereoRectify によって計算される行列のような,任意の行列である. 疎な点集合 {(x,y,d),...} を三次元空間に投影するには, cvPerspectiveTransform を持ちいる.