このセクションで述べる関数は,いわゆるピンホールカメラモデルを取り扱います.つまりこのモデルでは,3次元座点を透視投影変換を用いて画像平面に射影することで,シーンのビューが構成されています.
または
ここで はワールド座標系の3次元座標を表し は画像平面に投影された点の座標を表します. は,カメラ行列,またはカメラの内部パラメータ行列と呼ばれます. は主点(通常は画像中心), はピクセル単位で表される焦点距離です. したがって, あるファクタによってカメラ画像がスケーリングされている場合, このすべてのパラメータを同じファクタでスケーリング(それぞれが,拡大または縮小)する必要があります. 内部パラメータ行列はビューに依存しないので,一度推定すれば(ズームレンズの場合)焦点距離を固定している限りは繰返し使用することができます. 並進-回転の同次変換行列である は,外部パラメータ行列と呼ばれます. これは,静的環境に対するカメラの動き,または逆に,固定カメラの前の物体の剛体運動を表します. つまり は,点座標 をそれぞれのカメラの座標系に変換します. 上述の変換は,以下の式(で の場合)と等価です.
実際のカメラレンズは,主に半径方向の歪みや,わずかに円周方向の歪みを持っているので,上のモデルは以下のように拡張されます.
, , は半径方向の歪み係数, , は円周方向の歪み係数です.
OpenCV では高次の係数は考慮されません.以降の関数では,歪み係数は
というベクトルとして,渡されたり返されたりします.つまり,ベクトルが4つの要素をもつならば, であることを意味します.
歪み係数はシーンのビューに依存しないので,カメラの内部パラメータに属します. また,キャプチャされた画像の解像度に関わらず同じ値のままになります. つまり,例えば,あるカメラが の画像でキャリブレーションされた場合,同じカメラの の画像に対してもまったく同じ歪み係数を用いることができます ( , , , は適切にスケーリングされなければいけませんが).
以降の関数は,このようなモデルを用いて,次のようなことを行います:
楕円平面状の物体(例えば,腕)に対するホモグラフィ行列を求めます.
パラメタ: |
|
---|
この関数は,3次元楕円体の主軸で定義されるような,画像平面から平面への変換を行うホモグラフィ行列を求めます (OpenCV Guide の 3D Reconstruction の章にある図6-10を参照してください).
キャリブレーションパターンを写した複数のビューから,カメラの内部・外部パラメータを求めます.
パラメタ: |
|
---|
この関数は,カメラの内部パラメータ,および各ビューにおける外部パラメー タを推定します.各画像における,3次元点の座標と,それに対応する2次元の 投影点の座標を指定する必要があります.これは,幾何的な特徴が既知で,容 易に特徴点を検出できるような物体を用いて行われます.
そのような物体は,キャリブレーション器具またはキャリブレーションパターンと呼ばれます.OpenCVは元々,キャリブレーション器具としてチェスボードをサポートしています( FindChessboardCorners を参照してください).現在のところ,内部パラメータの初期化は,(物体上の点群のz-座標がすべて0になる)平面キャリブレーションパターンに対してのみ実装されています( CV_CALIB_USE_INTRINSIC_GUESS がセットされない場合).初期 cameraMatrix が与えられれば,3次元のキャリブレーション器具も利用することができます.
このアルゴリズムは,次のようになります:
この関数は,最終的な再投影誤差を返します.
注意:正方ではない(NxN ではない)グリッドを使用して, findChessboardCorners() でキャリブレーションを行う場合に, calibrateCamera が不正な値(つまり,歪み係数が0,画像中心が から遠く離れている,さらに/または, と が大きく異なる(比率が 10:1 以上))を返すとすると, FindChessboardCorners で patternSize=cvSize(rows,cols) としている可能性があります.正しくは, patternSize=cvSize(cols,rows) となります.
参考: FindChessboardCorners , FindExtrinsicCameraParams2 , initCameraMatrix2D() , StereoCalibrate , Undistort2
ステレオペアの片方の画像上の点に対して,それに対応する別の画像上のエピポーラ線を求めます.
パラメタ: |
|
---|
この関数は,ステレオペアの2つの画像の片方に存在する点それぞれに対して,対応する別の画像上のエピポーラ線を求めます.
F行列の定義から( FindFundamentalMat を参照してください),1番目の画像(つまり, whichImage=1 )上の点 に対する,2番目の画像上の線 は次のように求められます:
そして,逆に whichImage=2 の場合, は, から,次のように求められます:
エピポーラ線の係数には,スケールが定義されています.これらは というように正規化されます.
点座標と同次座標を,互いに変換します.
パラメタ: |
|
---|
この関数は, 2次元または3次元の点と,同次座標を相互に変換,あるいは単に コピーや転置 を行います.入力配列の次元数が出力よりも大きい場合は,各座標値が最後の座標値で割られます:
出力配列の次元数の方が大きい場合は,各入力点に値1が付け加えられます.それ以外の場合は単に,入力配列が出力配列にコピーされます(転置することもできます).
注意 :この関数は様々な形式の配列を入力にとるので,入出力配列の次元があいまいな場合はエラーが起こることもあります. 個の点,あるいは,マルチチャンネルで Nx1 または 1xN の配列,に対して利用する場合は,常に安全です
物体情報を含む構造体を初期化します.
パラメタ: |
|
---|
この関数は,物体情報構造体のメモリを確保し,物体逆行列を計算します.
事前に処理された物体データは,OpenCV 内部で構造体 CvPOSITObject に格納されるので,ユーザが構造体データに直接アクセスすることはできません.つまり,ユーザはこの構造体を作成し,そのポインタをこの関数に渡すだけです.
物体は,ある座標系の点座標の集合として定義されます.そして,関数 POSIT は,カメラ座標系の中心から,物体の points[0] へのベクトルを計算します.
与えられた物体に対する処理が終わった後は,関数 ReleasePOSITObject を呼んでメモリを解放しなければいけません.
ブロックマッチングステレオ対応点探索の構造体を作成します.
Parameter: | preset – あらかじめ定義されたパラメータセットのID.どのパラメータも,この構造体を作成した後に上書きすることができます.この値は次のようになります
|
---|
}
Parameter: | numberOfDisparities – 視差数.このパラメータが0の場合,preset から取得した値を利用します.そうでない場合,この値が preset の値を上書きします |
---|
この関数は,ステレオ対応点探索の構造体を作成し,それを初期化します.また, FindStereoCorrespondenceBM 呼び出しまでの間ならばいつでも,すべてのパラメータを上書きすることが可能です.
グラフカットに基づくステレオ対応点探索アルゴリズムの構造体を作成します.
パラメタ: |
|
---|
この関数は,ステレオ対応点探索の構造体を作成し,それを初期化します.また, FindStereoCorrespondenceGC 呼び出しまでの間ならばいつでも,すべてのパラメータを上書きすることが可能です.
ブロックマッチングステレオ対応点探索アルゴリズムのための構造体.
typedef struct CvStereoBMState
{
// 事前フィルタ(入力画像を正規化します):
int preFilterType; // 現在は 0
int preFilterSize; // 約 5x5..21x21
int preFilterCap; // 約 31 までの値
// 絶対値の差の合計(SAD)を用いて対応点探索を行います:
int SADWindowSize; // おそらく 5x5..21x21
int minDisparity; // 最小視差 (=0)
int numberOfDisparities; // 最大視差 - 最小視差
// 事後フィルタ(不良なマッチを除外します):
int textureThreshold; // テクスチャがない領域を無視します.
int uniquenessRatio; // 別の視差でもステレオ対応するようなピクセルを,
// 視差が無効なものとします.
int speckleWindowSize; // 除去されるスペックルの最大面積
// ( 0 にするとスペックルフィルタリングは無効になります)
int speckleRange; // 各連結成分において,許容される視差範囲
int trySmallerWindows; // 利用されません
CvRect roi1, roi2; // クリッピングするための ROI
int disp12MaxDiff; // left-right チェックを行う際の,最大許容視差
// 内部データ
...
}
CvStereoBMState;
- preFilterType¶
- 事前フィルタの種類. CV_STEREO_BM_NORMALIZED_RESPONSE あるいは,デフォルトかつ推奨値である CV_STEREO_BM_XSOBEL のどちらか, int
- preFilterSize¶
- 5x5..21x21,int
- preFilterCap¶
- 31 までの値,int
- SADWindowSize¶
- 5x5..21x21 あるいは,それ以上の値.ただし,21x21 以下のサイズの窓であれば,処理がだいぶ高速です,int
- minDisparity¶
- 最小視差 (=0),int
- numberOfDisparities¶
- 最大視差 - 最小視差,int
- textureThreshold¶
- テクスチャ閾値.つまり, SADWindowSize × SADWindowSize の近傍で求められた x-微分の絶対値の総和がこのパラメータよりも小さければ,その対象ピクセルでは視差が計算されません,int
- uniquenessRatio¶
- 求められた視差が有功になるための,最良(最小)のコスト関数値と2番目に良い値との最小マージン(パーセント単位)
- speckleWindowSize¶
- 除去されるスペックルの最大面積( 0 にするとスペックルフィルタリングは無効になります),int
- speckleRange¶
- 各連結成分において,許容される視差範囲,int
- trySmallerWindows¶
- 現在は利用されていません(0),int
- roi1, roi2
- 左右の画像をクリッピングするためのROI.関数 StereoRectify は,左右の画像の最大の矩形を返します.また,この平行化変換後もすべてのピクセルが有効になります.これらの矩形を CvStereoBMState 構造体にコピーすると,ステレオ対応点探索関数は自動的に, GetValidDisparityROI によって求められた「有効な」視差矩形の外側のピクセルをクリアします.よって,通常よりも「無効な視差」ピクセルが多くなりますが,残ったピクセルは,より有効である可能性が高いものになります
- disp12MaxDiff¶
- 明示的に求められた左から右への視差マップと,黙示的に( ValidateDisparity によって)求められた右から左への視差マップとの間の,許容される最大の差.この差が指定の閾値よりも大きいピクセルでの視差は無効になります.デフォルトでは,このパラメータは(-1)にセットされており,これは left-right チェックが行われないことを意味します
Kurt Konolige によるブロックマッチングによるステレオ対応点探索アルゴリズムは,非常に高速なシングルパスのステレオマッチングアルゴリズムです.これは,左右の画像において比較するピクセル位置のずれを( minDisparity から minDisparity+numberOfDisparities まで)変化させながら,輝度値の差の絶対値の総和を画像全体に渡って計算します.このアルゴリズムは, の画像のペアにおいて,その視差を O(W*H*numberOfDisparities) 回計算します.また,このアルゴリズムは,視差画像の質と信頼性を向上させるために,事前フィルタおよび事後フィルタを導入しています.
このアルゴリズムは,対応するブロックを,x-軸方向にのみ探索する事に注意してください.つまり,この関数の適用対象となるのは,平行化されたステレオペアです.また,垂直ステレオは直接はサポートされていませんが,そのような場合,ユーザは画像を転置させればよいでしょう.
グラフカットに基づく,ステレオ対応点探索アルゴリズムのための構造体.
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; // 反復計算回数.ユーザが定義します.
// internal buffers
CvMat* left;
CvMat* right;
CvMat* dispLeft;
CvMat* dispRight;
CvMat* ptrLeft;
CvMat* ptrRight;
CvMat* vtxBuf;
CvMat* edgeBuf;
}
CvStereoGCState;
Kolmogrov03 で( KZ1 として)紹介されたグラフカットステレオ対応点探索アルゴリズムは,非リアルタイムのステレオマッチングアルゴリズムであり,通常,明確なオブジェクト境界を示す非常に正確な奥行き画像を求めます.このアルゴリズムは,ステレオ問題を2値最適化問題のシーケンスとして扱い,それぞれを最大流アルゴリズム(max flow algorithm)を用いて解きます.上述の構造体は,手動で確保,初期化されるべきではりません.その代わりに, cvCreateStereoGCState を利用し,必要ならばパラメータを上書きしてください.
射影行列を,回転行列とカメラ行列に分解します.
パラメタ: |
|
---|
この関数は,射影行列をカメラ行列と回転行列,カメラの位置に分解します.
またオプションとして,各軸周りの3つの回転行列,そしてOpenGLで利用できる3つのオイラー角を得ることができます.
この関数は, RQDecomp3x3 に基づいています.
検出されたチェスボードのコーナーを描画します.
パラメタ: |
|
---|
この関数は,検出された個々のチェスボードを描画します.チェスボードが不完全に検出された場合は,コーナーが赤い丸で描画され,完全に検出された場合は,色付きのコーナーが線で結ばれます.
チェスボードの内側コーナー位置を求めます.
パラメタ: |
|
---|
この関数は,入力画像がチェスボードパターンを写すビューであるかどうかを判断し,もしそうならば,チェスボードの内側コーナーの位置を検出しようとします.これは,すべてのチェスボードコーナーが検出された場合は真値を返し,そのコーナーは特定の順序(1行ごとに,各行は左から右に)で格納されます.そうでない場合,つまり,コーナーの完全な検出や順序づけに失敗した場合は,0を返します.例えば,標準的なチェスボードは, 8 x 8 マスで 7 x 7 個の内側コーナー,つまり黒い正方形が別の黒い正方形と接触する点,をもちます.検出される座標は近似されたもので,より正確な位置を決定するために,関数 FindCornerSubPix を利用する場合があります.
注意: この関数では,様々な環境下でロバストな検出を行うために,チェスボードの周囲に(太い枠淵のような,広ければ広いほど良い)空白が必要です(もし,この空白がなく背景が暗ければ,外側の黒い正方形が適切に分離されず,正方形のグルーピングと順序付けアルゴリズムは失敗するでしょう).
3次元-2次元の対応点から,物体の姿勢を求めます.
パラメタ: |
|
---|
この関数は,カメラ行列や歪み係数と共に,物体上の点座標とそれに対応する画像上の投影点の集合が与えられた場合に,物体の姿勢を推定します.そのような姿勢は,再投影誤差を最小にするように求められます.つまり,観測された投影点 imagePoints と( ProjectPoints2 を用いて) objectPoints を投影した点との距離の2乗和を最小にします.
2つの画像の対応点からF行列を求めます.
パラメタ: |
|
---|
エピポーラ幾何は,次の式で説明されます:
ここで, はF行列, と はそれぞれ,1番目と2番目の画像での対応点を表します.
この関数は,上述の4つの手法の内の1つを用いてF行列を計算し, 求められたF行列の個数(1または3)を返し,求まらなかった場合は0 を返します. 通常,行列は1つだけ求められますが,7-point アルゴリズムを利用する場合,この関数は3つまでの解(すべての行列を順番に格納した の行列)を返すことがあります
計算されたF行列はさらに,指定された点に対応するエピポーラ線を求める関数 ComputeCorrespondEpilines に渡される場合があります.また,平行化変換を求めるために StereoRectifyUncalibrated に渡すこともできます.
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.fl[i*2] = <x,,1,i,,>;
points1->data.fl[i*2+1] = <y,,1,i,,>;
points2->data.fl[i*2] = <x,,2,i,,>;
points2->data.fl[i*2+1] = <y,,2,i,,>;
}
fundamental_matrix = cvCreateMat(3,3,CV_32FC1);
int fm_count = cvFindFundamentalMat( points1,points2,fundamental_matrix,
CV_FM_RANSAC,1.0,0.99,status );
2つの画像間の透視変換を求めます.
パラメタ: |
|
---|
この関数 は,元平面と目的平面との間の透視変換 を求め ます:
つまり,以下の逆投影誤差を最小化します.
パラメータ method がデフォルト値の 0 にセットされた場合,この関数はすべての点の組を利用して,単純な最小二乗法によりホモグラフィ行列を推定します.
しかし,透視投影変換ですべての点の組( , )を一致させることができない(つまり,外れ値がある)場合でも,ロバストな手法を選択することで正しい変換を推定することができます. RANSAC と LMedS のどちらの手法も,対応する点の組のランダムな部分集合(各4組)を繰り返し生成し,この部分集合と単純な最小二乗法を用いてホモグラフィ行列を推定します.そして,求められたホモグラフィ行列の質/状態(RANSACの場合はインライアの数,LMedS推定の場合は中央値の逆投影誤差)を計算します. この最適な部分集合から,ホモグラフィ行列の初期推定値とインライア/アウトライアのマスクが生成されます.
手法がロバストかどうかにかかわらず,求められたホモグラフィ行列は,逆投影誤差がより小さくなるように,Levenberg-Marquardt 法を用いてさらに(ロバスト推定の場合はインライア値のみを利用して)高精度化されます.
RANSAC を指定すると,実際にはどれだけアウトライアが混ざったデータも扱うことができますが,インライアとアウトライアを区別するための閾値が必要となります. LMedS を指定すると,この様な閾値は必要なくなりますが,データの50 % 以上がインライアでなければ正しく動作しません. また,計算された特徴点列内存在するノイズが僅かであり,アウトライアがないことが分かっている場合は,デフォルトの手法が最も良い選択です.
%– correctly only when there are more than 50 % of inliers. Finally,
この関数は,内部および外部パラメータ行列の初期推定値を求めるために利用されます. ホモグラフィ行列は,スケールに依存するので, となるように正規化されます.
参考: GetAffineTransform , GetPerspectiveTransform , EstimateRigidMotion , WarpPerspective , PerspectiveTransform
ブロックマッチングアルゴリズムを用いて視差画像を求めます.
パラメタ: |
|
---|
この関数は,入力された平行化されたステレオ画像ペアに対する視差マップを計算します.(視差が計算できないような)無効なピクセルの値は state->minDisparity - 1 (16ビット固定小数点視差マップの場合は, (state->minDisparity-1)*16 )にセットされます
グラフカットアルゴリズムを用いて視差マップを求めます.
パラメタ: |
|
---|
この関数は,平行化された入力ステレオ画像ペアに対する視差マップを計算します.左視差画像は,次の範囲の値を含むことに注意してください:
または
そして,右視差画像は,次の範囲の値を含みます:
または
つまり,右視差画像と左視差画像では範囲が逆になっています.そして,マッチング結果がよくないピクセルは,オクルージョンとして処理されます.
以下は,この関数の使用例です:
// 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.pgm", disparity_left_visual );
フリースケーリングパラメータに基づいて,新たなカメラ行列を返します
パラメタ: |
|
---|
この関数は,フリースケーリングパラメータに基づいて,最適な新しいカメラ行列を求め ます.このパラメータを変化させることで,ユーザは目的にあうピクセルだけを取り出したり alpha=0 ,コーナーを重要視して,すべての元画像ピクセルを保持したり alpha=1 ,あるいはその中間で,何か別のピクセルを得たりします.また, alpha>0 の場合,歪み補正された結果には,補正前の画像の外側にある「仮想」ピクセルに対応した黒いピクセルが含まれる可能性があります.元のカメラ行列,歪み係数,求められた新しいカメラ行列,そして newImageSize は, Remap 用のマップを生成するために InitUndistortRectifyMap に渡されるべきものです.
3次元-2次元の対応点から,カメラの内部パラメータ行列を求めます.
パラメタ: |
|
---|
この関数は,キャリブレーション処理のためのカメラ行列の初期値を推定します.
現在のところ,平面のキャリブレーション器具,つまり,物体上の点の z-座標=0 となるようなもののみをサポートします.
歪み補正マップを求めます.
パラメタ: |
|
---|
この関数は, InitUndistortRectifyMap を単純化した形式です.ここでは,平行化変換 R が単位行列と newCameraMatrix=cameraMatrix になっています.
歪み補正および平行化変換のマップを求めます.
パラメタ: |
|
---|
この関数は,歪み補正変換と平行化変換を結合させた変換を求め,その結果を Remap 用のマップの形式で表現します.歪み補整された画像は,まるで,カメラ行列が =newCameraMatrix で歪みを持たないカメラで撮影したかのような画像に見えます.単眼カメラの場合,通常, newCameraMatrix は cameraMatrix と等しくなるか,あるいはスケーリングを制御する必要があれば GetOptimalNewCameraMatrix によって求められます.ステレオカメラの場合,通常, newCameraMatrix は StereoRectify によって求められた P1 または P2 にセットされます.
また,この新しいカメラは, R に従って,個別に座標空間内での方向が決められます.これにより,例えば,ステレオカメラの両方の画像のエピポーラ線が平行で,同じy-座標を持つように各カメラを揃えることができるようになります (これは,横に並んだステレオカメラの場合です).
この関数は,実際に Remap で利用される逆マッピングアルゴリズム用のマップを生成ます.すなわち,この関数は,(歪み補正,平行化された)出力画像の各ピクセル 毎に,それに対応する元画像(つまり,カメラからのオリジナル画像)の座標を求めます.その処理は,以下のようになります:
ここで は,歪み係数を表します.
ステレオカメラの場合,この関数は,各カメラ毎に1度ずつ,2度呼ばれます. StereoCalibrate の後 StereoRectify が呼ばれ,そしてこの関数が呼び出されます.しかし,ステレオカメラがキャリブレーションされていなかった場合でも, StereoRectifyUncalibrated を用いてF行列から直接,平行化変換を求めることが可能です.この関数は,各カメラに対して,3次元空間における回転行列 R ではなく,ピクセル領域における平行化変換として,ホモグラフィ行列 H を求めます. R は, H から次のようにして求めることができます:
ここで cameraMatrix は,任意に選ぶことができます.
POSITアルゴリズムを実行します.
パラメタ: |
|
---|
この関数は,POSITアルゴリズムの実装です.画像座標は,カメラ座標系で与えられます.また,焦点距離は,カメラキャリブレーション関数を利用して取得できます.このアルゴリズムの各試行において,新たな推定姿勢の透視投影が計算されます.
(前の試行と今の試行の)2つの投影間の差分ノルムは,それぞれに対応する点間の最大距離です.パラメータ criteria.epsilon は,この差が小さくなった場合にアルゴリズムを停止するために利用されます.
3次元点を画像平面に投影します.
パラメタ: |
|
---|
この関数は,カメラの内部・外部パラメータが与えられると,3次元点を画像平面に投影します. オプションとして,この関数はヤコビ行列,つまり画像点を入力パラメータすべての関数とみなし,特定のカメラパラメータ,内部および/または外部パラメータで偏微分した行列,を求めます. 求められたヤコビ行列は, CalibrateCamera2 , FindExtrinsicCameraParams2 そして StereoCalibrate での大域的最適化において利用されます.この関数自身も,現在の内部・外部パラメータが与えられた場合の再投影誤差を求めるために利用されます.
rvec=tvec=(0,0,0) ,または 3x3 の単位行列にするために distCoeffs=Mat() とセットすることによって,この関数を利用した様々な部分事例を得ることができることに注意してください.つまり,疎な点集合に対する歪んだ座標を求めたり,歪みのない理想的なものとして透視変換を適用したり(そして,その微分を求めたりも)できます.
視差画像を3次元空間に再投影します.
パラメタ: |
|
---|
この関数は,1チャンネルの視差マップを,3次元面を表現する3チャンネルの画像に変換します.つまり,各ピクセル (x,y) と,それに対応する視差 d=disparity(x,y) に対して,次のように計算されます:
行列 Q は,例えば, StereoRectify によって求められるような任意の 行列です.疎な点集合 {(x,y,d),...} を3次元空間に再投影するためには, PerspectiveTransform を利用します.
3x3 行列の ‘RQ’ 分解を行います.
パラメタ: |
|
---|
この関数は,ギブンス回転を利用して RQ 分解を行います.これは, DecomposeProjectionMatrix において,射影行列の左 3x3 部分行列を,カメラ行列と回転行列に分解するために利用されます.
またオプションとして,各軸周りの3つの回転行列,そしてOpenGLで利用できる3つのオイラー角を 得ることができます.
3次元物体情報構造体を解放します.
Parameter: | posit_object – 構造体 CvPOSIT へのダブルポインタ |
---|
この関数は,事前に関数 CreatePOSITObject によって確保されたメモリを解放します.
ブロックマッチングステレオ対応点探索構造体を解放します.
Parameter: | state – 解放される構造体へのダブルポインタ |
---|
この関数は,ステレオ対応点探索構造体と,関連する全ての内部バッファを解放します.
グラフカットに基づくステレオ対応点探索アルゴリズムのための状態構造体を解放します.
Parameter: | state – 解放される構造体へのダブルポインタ |
---|
この関数は,ステレオ対応点探索構造体と,関連する全ての内部バッファを解放します.
回転行列と回転ベクトルを相互に変換します.
パラメタ: |
|
---|
以下の関係から,逆変換も簡単に行うことができます.
回転ベクトルは,便利で最もコンパクトな回転行列の表現方法です(すべての回転行列は丁度3自由度なので). この表現方法は, CalibrateCamera2 , StereoCalibrate または FindExtrinsicCameraParams2 のような3次元幾何学の大域的最適化処理において利用されます.
ステレオカメラのキャリブレーションを行います.
パラメタ: |
|
---|
この関数は,ステレオペアを構成する2つのカメラ間の変換を推定します.2つのカメラの相対位置と相対姿勢が固定されたステレオカメラがあり,1番目のカメラと2番目のカメラに対する物体の姿勢 (R1, T1) と (R2, T2) をそれぞれ計算したとすると,これらの姿勢は明らかに互いに関係があります.つまり, ( , ) が与えられると, ( , ) を求めることができるので,我々は,2番目のカメラの1番目のカメラに対する位置と姿勢さえ知っていればよいことになります.これが,この関数の働きです.これは ( , ) を次のように求めます:
またオプションとして,E 行列を求めます.
ここで は,並進ベクトル : の要素を表します.さらに,この関数は F行列も求めることができます.
この関数は,ステレオカメラの位置姿勢関係を求めるだけでなく,2つのカメラそれぞれの完全なキャリブレーションも行うことができます.しかし,パラメータ空間の次元が大きすぎる事や,入力データのノイズなどが原因で,最適解を得られない可能性もあります.したがって,各カメラの内部パラメータを(例えば CalibrateCamera2 を用いて)個々に高精度に推定できるならば,そちらの方法が推奨されます.その後に,その計算された内部パラメターと CALIB_FIX_INTRINSIC フラグをこの関数に渡せばよいです.それが無理で,全てのパラメータを一度に計算する場合,いくつかのパラメータに制限を与えると良いでしょう.例えば, CV_CALIB_SAME_FOCAL_LENGTH フラグと CV_CALIB_ZERO_TANGENT_DIST フラグを指定することは,通常は妥当な仮定と言えます.
CalibrateCamera2 と同様に,この関数は,両方のカメラのすべてのビューのすべての点の再投影誤差の和を最小化します.
また,この関数は,最終的な再投影誤差を返します.
キャリブレーション済みステレオの,それぞれのカメラの平行化変換を求めます.
パラメタ: |
|
---|
この関数は,各カメラの回転行列を求めます.この回転行列によって,両方のカメラの画像平面が(仮想的に)同一平面に乗るように変換されます.その結果,すべてのエピポーラ線が平行になるので,多数のステレオ対応点探索問題が単純化されます.この関数は, stereoCalibrate() によって求められた行列を入力にとり,2つの回転行列と,新しい座標系における2つの投影行列を出力します.この関数は,次の2つの場合を区別します:
平行化された画像では,左右のカメラ間のエピポーラ線は,水平,かつ,同じ y-座標(高さ)になる.P1 と P2 は,以下のようになります:
ここで, はカメラ間の水平方向のずれであり, CV_CALIB_ZERO_DISPARITY がセットされている場合は となります.
平行化された画像でのエピポーラ線は,垂直,かつ,同じ x-座標になる.P1 と P2 は,以下のようになります:
ここで, はカメラ間の垂直方向のずれであり, CALIB_ZERO_DISPARITY がセットされている場合は となります.
見ての通り, P1 と P2 の最初の3列は,「平行化された」新たなカメラ行列そのものです.
The matrices, together with R1 and R2 , can then be passed to InitUndistortRectifyMap to initialize the rectification map for each camera.
以下は, stereo_calib.cpp サンプルのスクリーンショットです.ここに示される赤い水平線は,対応する画像領域を通過しています.つまり,(多くのステレオ対応点探索アルゴリズムが前提とするように)両方の画像が綺麗に平行化されていることが分かります.また,緑の矩形は, roi1 と roi2 を示し,その中が確かにすべて有効なピクセルであることが分かります.
キャリブレーションされていないステレオの,それぞれのカメラの平行化変換を求めます.
パラメタ: |
|
---|
この関数は,カメラの内部パラメータや空間の相対的位置を必要とすることな く,平行化変換を求めます.なので,「Uncalibrated」という接尾辞がついています. StereoRectify とのもう一つの違いとして,関数の出力が,物体(3次元)空間における平行化変換ではなく,ホモグラフィ行列 H1 と H2 によってエンコードされた平面透視変換となることが挙げられます.この関数は,アルゴリズム Hartley99 の実装です.
このアルゴリズムは,カメラの内部パラメータを知る必要はありませんが,エピポーラ幾何に大きく依存していることに注意してください.したがって,カメラレンズが大きく歪んでいる場合は,F行列を計算してこの関数を呼び出すよりも前に,歪みを補正しておくのが賢明です.例えば,ステレオの各カメラの歪み係数は, CalibrateCamera2 を用いて個別に推定できます.画像は Undistort2 によって,点座標だけならば UndistortPoints によって補正することが可能です.
レンズ歪みを補正するように画像を変形させます.
パラメタ: |
|
---|
この関数は,半径方向および円周方向のレンズ歪みを補正するように画像を変換します.
この関数は,単に InitUndistortRectifyMap ( R は単位行列)と Remap (バイリニア補間)を組み合わせたものです.変換の詳細については,前述の関数を参照してください.
元画像に対応するピクセルが存在しないような出力画像のピクセルは,0(黒色)で埋められます.
補正された画像内に残っている元画像の部分画像は newCameraMatrix で制御できます.ユーザは,必要に応じた適切な newCameraMatrix を求めるために GetOptimalNewCameraMatrix を利用することができます.
これらのカメラ行列と歪みパラメータは CalibrateCamera2 を用いて決定できます. 画像の解像度がキャリブレーション時と異なる場合,歪み係数はそのままで構いませんが, および を適宜スケーリングする必要があります
観測された点座標から,理想的な点座標を求めます.
パラメタ: |
|
---|
この関数は, Undistort2 や InitUndistortRectifyMap と似ていますが,ラスタ画像の代わりに,疎な点集合を扱います.また, ProjectPoints2 に対する逆変換のような処理も行います(3次元物体の場合は,当然その3次元座標を再構成するわけではありません.しかし,平面物体の場合は,適切な R が指定されれば,並進ベクトル次第で,そのようなことも起こります).
// (u,v) は入力点座標, (u', v') は出力点座標
// camera_matrix=[fx 0 cx; 0 fy cy; 0 0 1]
// P=[fx' 0 cx' tx; 0 fy' cy' ty; 0 0 1 tz]
x" = (u - cx)/fx
y" = (v - cy)/fy
(x',y') = undistort(x",y",dist_coeffs)
[X,Y,W]T = R*[x' y' 1]T
x = X/W, y = Y/W
u' = x*fx' + cx'
v' = y*fy' + cy',
ここで undistort() は,正規化された歪んだ点座標から,正規化されたオリジナルの点座標を推定する,反復近似アルゴリズムです(「正規化された」というのは,座標がカメラ行列に依存しないという意味です).
この関数は,ステレオの各カメラや単眼カメラに対して用いることができます(Rは NULL ).