cvCalcCovarMatrix, cvInvert, cvMahalanobisの合わせ技でマハラノビス距離を求める.

void cvCalcCovarMatrix( CvMat** data, int count, CvMat* result, CvMat* average, int flags);

引数

  • 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でスケーリングする

返り値

  • void型なのでなし

double cvMahalanobis( CvMat* reference, CvMat* vector, CvMat* matrix );

引数

  • reference:CvMat*型のベクトル
  • vector:CvMat*型のベクトル
  • matrix:CvMat*型の逆共分散行列

返り値

  • referenceとvectorのマハラノビス距離

解説

  • 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などを用いる(クラス中心)
  • cvMahalonobis(マハロビス)というエイリアスがある

サンプルコード

通常の求め方

#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も同様)

#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); //計算した逆共分散行列からマハラノビス距離を計算

実体ファイル

  • cxcore/include/cxcore.h
  • cxcore/src/cxmatmul.cpp

:OpenCV:OpenCV 1.1準拠


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-05-27 (木) 11:37:11 (2734d)