/** @file */ /* The MIT License * * Copyright (c) 2008, Naotoshi Seo * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #ifndef CV_GMMPDF_INCLUDED #define CV_GMMPDF_INCLUDED #include "cv.h" #include "cvaux.h" #include #include #define _USE_MATH_DEFINES #include #include "cvgausspdf.h" //CVAPI(void) //cvMatGmmPdf( const CvMat* samples, const CvMat* means, CvMat** covs, // const CvMat* weights, CvMat* probs, bool normalize = false ); //CV_INLINE double //cvGmmPdf( const CvMat* sample, const CvMat* means, CvMat** covs, // const CvMat* weights, CvMat* probs = NULL, bool normalize = false ); /** * Compute gaussian mixture pdf for a set of sample vectors * * Example) * @code * const int D = 2; * const int N = 3; * const int K = 2; * * double vs[] = { 3, 4, 5, * 3, 4, 5 }; * col vectors * double ms[] = { 3, 5, * 3, 5 }; * col vectors * double cs0[] = { 1, 0, * 0, 1 }; * double cs1[] = { 1, 0.1, * 0.1, 1 }; * double ws[] = { 0.5, 0.5 }; * * CvMat vecs = cvMat(D, N, CV_64FC1, vs); * CvMat means = cvMat(D, K, CV_64FC1, ms); * CvMat **covs = (CvMat**)cvAlloc( K * sizeof(*covs) ); * covs[0] = &cvMat(D, D, CV_64FC1, cs0); * covs[1] = &cvMat(D, D, CV_64FC1, cs0); * CvMat weights = cvMat( 1, K, CV_64FC1, ws); * CvMat *probs = cvCreateMat(K, N, CV_64FC1); * cvMatGmmPdf( &vecs, &means, covs, &weights, probs, false); * cvMatPrint( probs ); * cvReleaseMat( &probs ); * cvFree( &covs ); * @endcode * * @param samples D x N data vector (Note: not N x D for clearness of matrix operation) * @param means D x K mean vector * @param covs (D x D) x K covariance matrix for each cluster * @param weights 1 x K weights * @param probs K x N or 1 x N computed probabilites * @param normalize Compute normalization term or not * @see cvGaussPdf */ CVAPI(void) cvMatGmmPdf( const CvMat* samples, const CvMat* means, CvMat** covs, const CvMat* weights, CvMat* probs, bool normalize CV_DEFAULT(true) ) { int D = samples->rows; int N = samples->cols; int K = means->cols; int type = samples->type; CV_FUNCNAME( "cvMatGmmPdf" ); // error handling __CV_BEGIN__; CV_ASSERT( CV_IS_MAT(samples) ); CV_ASSERT( CV_IS_MAT(means) ); for( int k = 0; k < K; k++ ) CV_ASSERT( CV_IS_MAT(covs[k]) ); CV_ASSERT( CV_IS_MAT(weights) ); CV_ASSERT( CV_IS_MAT(probs) ); CV_ASSERT( D == means->rows ); for( int k = 0; k < K; k++ ) CV_ASSERT( D == covs[k]->rows && D == covs[k]->cols ); // D x D CV_ASSERT( 1 == weights->rows && K == weights->cols ); // 1 x K CV_ASSERT( ( 1 == probs->rows || K == probs->rows ) && N == probs->cols ); // 1 x N or K x N CvMat *mean = cvCreateMat( D, 1, type ); const CvMat *cov; CvMat *_probs = cvCreateMat( 1, N, type ); cvZero( probs ); for( int k = 0; k < K; k++ ) { cvGetCol( means, mean, k ); cov = covs[k]; cvMatGaussPdf( samples, mean, cov, _probs, normalize ); cvConvertScale( _probs, _probs, cvmGet( weights, 0, k ) ); if( 1 == probs->rows ) { cvAdd( probs, _probs, probs ); } else { for( int n = 0; n < N; n++ ) { cvmSet( probs, k, n, cvmGet( _probs, 0, n ) ); } } } cvReleaseMat( &mean ); cvReleaseMat( &_probs ); __CV_END__; } /** * Compute gaussian mixture pdf * * @param sample D x 1 sample vector * @param means D x K mean vector for each cluster * @param covs (D x D) x K covariance matrix for each cluster * @param weights 1 x K weights * @param probs K x 1 probabilities for each cluster if want * @param normalize use normalization term or not * @return double prob * @see cvMatGmmPdf */ CV_INLINE double cvGmmPdf( const CvMat* sample, const CvMat* means, CvMat** covs, const CvMat* weights, CvMat* probs CV_DEFAULT(NULL), bool normalize CV_DEFAULT(true) ) { double prob; CvMat* _probs; int K = means->cols; if( probs ) _probs = probs; else _probs = cvCreateMat( K, 1, sample->type ); cvMatGmmPdf( sample, means, covs, weights, _probs, normalize ); prob = cvSum( _probs ).val[0]; if( !probs ) cvReleaseMat( &probs ); return prob; } #endif