cvCalcCovarMatrix, [[cvInvert>逆行列の計算]], cvMahalanobisの合わせ技でマハラノビス距離を求める.

#contents

*void cvCalcCovarMatrix( CvMat** data, int count, CvMat* result, CvMat* average, int flags); [#qd6433d9]

**引数 [#x8fc3841]
-data:CvMat**型の特徴ベクトル集合.CvMat*ではないのに注意.各要素は画像も可能
-count:int型のdataの個数
-result:CvMat*型の共分散行列
-average:CvMat*型の平均ベクトル
-flags:int型の動作フラグ
--CV_COVAR_NORMAL:通常の共分散行列
--CV_COVAR_SCRAMBLED:スクランブル共分散行列
--CV_COVAR_ROWS:data[0]の各行をサンプルとする
--CV_COVAR_COLS:data[0]の各列をサンプルとする
--CV_COVAR_USE_AVG:指定したaverageを平均ベクトルとして使う
--CV_COVAR_SCALE:共分散行列をcountでスケーリングする

**返り値 [#y0614db8]
-void型なのでなし

*double cvMahalanobis( CvMat* reference, CvMat* vector, CvMat* matrix ); [#pffbd2de]

**引数 [#oabc4181]
-reference:CvMat*型のベクトル
-vector:CvMat*型のベクトル
-matrix:CvMat*型の逆共分散行列

**返り値 [#ad66fc0a]
-referenceとvectorのマハラノビス距離

*解説 [#ce4b2102]
-flagsで共分散行列の求め方を指定する
--通常はCV_COVAR_NORMALで求める
--CV_COVAR_SCRAMBLEDは固有顔を求めるときに使うらしい
--CV_COVAR_SCRAMBLEDを使うと共分散行列の大きさはcount*countになる
--CV_COVAR_NORMALがCV_COVAR_SCRAMBLEDより優先される
--CV_COVAR_ROWSかCV_COVAR_COLSを指定した場合はdata[0]以外は無視される
--CV_COVAR_COLSがCV_COVAR_ROWSより優先される
--CV_COVAR_USE_AVGを指定しなかった場合は関数内で平均ベクトルを求めてaverageに格納される
-matrixは''逆''共分散行列
--cvCalcCovarMatrixで求めた共分散行列の逆行列を[[cvInvert>逆行列の計算]]で求める
--ランク落ちの可能性があるのでSVD(特異値分解)を利用する
-最終的にはreferenceとvectorのマハラノビス距離が求まる
-referenceにはaverageなどを用いる(クラス中心)
-cvMahal''o''nobis(マハロ''ノ''ビス)というエイリアスがある

*サンプルコード [#l2d7959a]
**通常の求め方 [#sc7d3ec7]
 #define MAX_DATA 500
 #define DEMIENSION 3
 int count;             //データの個数
 double distance;       //マハラノビス距離
 CvMat *data[MAX_DATA]; //クラス
 CvMat *result        = cvCreateMat( DIMENSION, DIMENSION, CV_32F); //共分散行列
 CvMat *inversecovar  = cvCreateMat( DIMENSION, DIMENSION, CV_32F); //逆共分散行列
 CvMat *average       = cvCreateMat( DIMENSION, 1, CV_32F);         //平均ベクトル
 CvMat *input         = cvCreateMat( DIMENSION, 1, CV_32F);         //比較するベクトル
 
 //クラスの読み込み
 //この場合dataの各要素は高さDIMENSION,幅1のベクトル
 count = ReadData( data, MAX_DATA);
 ReadInput( input);                                       //↓クラスから共分散行列を計算
 cvCalcCovarMatrix( data, count, result, average, CV_COVAR_NORMAL | CV_COVAR_SCALE);
 cvInvert( result, inversecovar, CV_SVD);                 //逆行列計算
 distance = cvMahalanobis( average, input, inversecovar); //計算した逆共分散行列からマハラノビス距離を計算

**CV_COVAR_COLSを使う場合(ROWSも同様) [#gefc795a]
 #define DEMIENSION 3
 int count = GetDataLength(); //データの個数
 double distance;             //マハラノビス距離
 CvMat *data          = cvCreateMat( DIMENSION, count, CV_32F);     //クラス
 CvMat *result        = cvCreateMat( DIMENSION, DIMENSION, CV_32F); //共分散行列
 CvMat *inversecovar  = cvCreateMat( DIMENSION, DIMENSION, CV_32F); //逆共分散行列
 CvMat *average       = cvCreateMat( DIMENSION, 1, CV_32F);         //平均ベクトル
 CvMat *input         = cvCreateMat( DIMENSION, 1, CV_32F);         //比較するベクトル
 
 //クラスの読み込み
 //この場合dataの要素数は1,dataの幅(列数)だけデータが存在する
 ReadData( data);
 ReadInput( input);                                       //↓クラスから共分散行列を計算
                                                          //CV_COVAR_COLS(ROWS)を指定しているので,countの指定は無効
 cvCalcCovarMatrix( &data, 0, result, average, CV_COVAR_NORMAL | CV_COVAR_SCALE | CV_COVAR_COLS);
 cvInvert( result, inversecovar, CV_SVD);                 //逆行列計算
 distance = cvMahalanobis( average, input, inversecovar); //計算した逆共分散行列からマハラノビス距離を計算

*実体ファイル [#o5423f0e]
-cxcore/include/cxcore.h
-cxcore/src/cxmatmul.cpp

[[:OpenCV]][[:OpenCV 1.1]]準拠

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