You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
5.4 KiB
168 lines
5.4 KiB
9 years ago
|
/** @file */
|
||
|
/* The MIT License
|
||
|
*
|
||
|
* Copyright (c) 2008, Naotoshi Seo <sonots(at)sonots.com>
|
||
|
*
|
||
|
* 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 <stdio.h>
|
||
|
#include <iostream>
|
||
|
#define _USE_MATH_DEFINES
|
||
|
#include <math.h>
|
||
|
|
||
|
#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
|