OpenCV 2.0 – cv::Mat 行列演算

前回に引き続き、cv::Matクラスについて。
今回は行列演算に関する機能を使います。

houteisiki

上記のシンプルな連立一次方程式を cv::Mat クラスの機能を使って解いてみます。

[cpp]
// 係数行列 A
float dataA[][3] = { {1.0, -2.0, 3.0}, {3.0, 1.0, -5.0}, {-2.0, 6.0, -9.0} };
// 行列 B
float dataB[] = {1.0, -4.0, -2.0};
Mat matA(3, 3, CV_32FC1, dataA);
Mat matB(3, 1, CV_32FC1, dataB);
Mat matX(3, 1, CV_32FC1);

// AX = B を解く. 両辺にAの逆行列を前掛けする
matX = matA.inv()*matB;

MatConstIterator_ iter = matX.begin();
while(iter != matX.end()) printf(“%.1f\n”, *iter++);
[/cpp]
? 出力結果

1.0 // x
3.0 // y
2.0 // z

CvMatでは cvmInvert -> cvmMul と関数を順番に呼び出さないといけないところを、
cv::Matなら matX = matA.inv()*matB のように直感的に行列演算を行うことができます。
また、今回のような線形な問題であれば solve(matA, matB, matX) で解くこともできます。

基本的な行列演算

CvMat cv::Mat
X = A + B cvmAdd(A, B, X) X = A + B
X = A – B cvmSub(A, B, X) X = A – B
X = AB cvmMul(A, B, X) X = A * B
X = A-1 (逆行列) cvmInvert(A, X) X = A.inv()
X = AT (転置行列) cvmTranspose(A, X) X = A.t()
X = A・B (内積) cvmDotProduct(A, B) X = A.dot(B)
X = A × B (外積) cvmCrossProduct(A, B, X) X = A.cross(B)
|A| (行列式) cvmDet(A) determinant(A)

以下のような細かい操作もできます。
[cpp]
matA*5.0; // 行列の各要素に5を掛ける (スケーリング)

matA.row(0) = matA.row(2)*2.0; // 3行目をスケーリングして1行目に (添字に注意)
[/cpp]

また、Matlabスタイルの行列初期化関数も用意されています。
[cpp]
Mat zero = Mat::zeros(3, 3, CV_32FC1); // 零行列を生成
Mat eye = Mat::eye(3, 3, CV_32FC1); // 単位行列を生成
Mat one = Mat::ones(3, 3, CV_32FC1); // 全要素が 1 の行列を生成
[/cpp]

これ以外にもまだまだたくさんの機能があります。
今まで面倒だった行列演算がかなり楽になるのでうれしいですね。

関連記事:
OpenCV 2.0 – cv::Mat
OpenCV 2.0 – cv::Ptr
OpenCV 2.0を試してみた

あわせて読む:

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です