Commit b8c31006 authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

modified EM interface; updated tests & samples

parent 1c1c6b98
...@@ -66,7 +66,6 @@ struct CV_EXPORTS CvMotionModel ...@@ -66,7 +66,6 @@ struct CV_EXPORTS CvMotionModel
} }
float low_pass_gain; // low pass gain float low_pass_gain; // low pass gain
cv::EM::Params em_params; // EM parameters
}; };
// Mean Shift Tracker parameters for specifying use of HSV channel and CamShift parameters. // Mean Shift Tracker parameters for specifying use of HSV channel and CamShift parameters.
...@@ -109,7 +108,6 @@ struct CV_EXPORTS CvHybridTrackerParams ...@@ -109,7 +108,6 @@ struct CV_EXPORTS CvHybridTrackerParams
float ms_tracker_weight; float ms_tracker_weight;
CvFeatureTrackerParams ft_params; CvFeatureTrackerParams ft_params;
CvMeanShiftTrackerParams ms_params; CvMeanShiftTrackerParams ms_params;
cv::EM::Params em_params;
int motion_model; int motion_model;
float low_pass_gain; float low_pass_gain;
}; };
...@@ -182,7 +180,6 @@ private: ...@@ -182,7 +180,6 @@ private:
CvMat* samples; CvMat* samples;
CvMat* labels; CvMat* labels;
cv::EM em_model;
Rect prev_window; Rect prev_window;
Point2f prev_center; Point2f prev_center;
......
...@@ -132,17 +132,6 @@ void CvHybridTracker::newTracker(Mat image, Rect selection) { ...@@ -132,17 +132,6 @@ void CvHybridTracker::newTracker(Mat image, Rect selection) {
mstracker->newTrackingWindow(image, selection); mstracker->newTrackingWindow(image, selection);
fttracker->newTrackingWindow(image, selection); fttracker->newTrackingWindow(image, selection);
params.em_params.covs = NULL;
params.em_params.means = NULL;
params.em_params.probs = NULL;
params.em_params.nclusters = 1;
params.em_params.weights = NULL;
params.em_params.covMatType = cv::EM::COV_MAT_SPHERICAL;
params.em_params.startStep = cv::EM::START_AUTO_STEP;
params.em_params.termCrit.maxCount = 10000;
params.em_params.termCrit.epsilon = 0.001;
params.em_params.termCrit.type = cv::TermCriteria::COUNT + cv::TermCriteria::EPS;
samples = cvCreateMat(2, 1, CV_32FC1); samples = cvCreateMat(2, 1, CV_32FC1);
labels = cvCreateMat(2, 1, CV_32SC1); labels = cvCreateMat(2, 1, CV_32SC1);
...@@ -222,12 +211,15 @@ void CvHybridTracker::updateTrackerWithEM(Mat image) { ...@@ -222,12 +211,15 @@ void CvHybridTracker::updateTrackerWithEM(Mat image) {
} }
cv::Mat lbls; cv::Mat lbls;
em_model.train(samples, cv::Mat(), params.em_params, &lbls);
EM em_model(1, EM::COV_MAT_SPHERICAL, TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 10000, 0.001));
em_model.train(cvarrToMat(samples), lbls);
if(labels) if(labels)
*labels = lbls; lbls.copyTo(cvarrToMat(labels));
curr_center.x = (float)em_model.getMeans().at<double> (0, 0); Mat em_means = em_model.get<Mat>("means");
curr_center.y = (float)em_model.getMeans().at<double> (0, 1); curr_center.x = (float)em_means.at<float>(0, 0);
curr_center.y = (float)em_means.at<float>(0, 1);
} }
void CvHybridTracker::updateTrackerWithLowPassFilter(Mat image) { void CvHybridTracker::updateTrackerWithLowPassFilter(Mat image) {
......
...@@ -1821,10 +1821,10 @@ public: ...@@ -1821,10 +1821,10 @@ public:
CV_WRAP virtual double calcLikelihood( const cv::Mat &sample ) const; CV_WRAP virtual double calcLikelihood( const cv::Mat &sample ) const;
CV_WRAP int getNClusters() const; CV_WRAP int getNClusters() const;
CV_WRAP const cv::Mat& getMeans() const; CV_WRAP cv::Mat getMeans() const;
CV_WRAP void getCovs(CV_OUT std::vector<cv::Mat>& covs) const; CV_WRAP void getCovs(CV_OUT std::vector<cv::Mat>& covs) const;
CV_WRAP const cv::Mat& getWeights() const; CV_WRAP cv::Mat getWeights() const;
CV_WRAP const cv::Mat& getProbs() const; CV_WRAP cv::Mat getProbs() const;
CV_WRAP inline double getLikelihood() const { return emObj.isTrained() ? likelihood : DBL_MAX; } CV_WRAP inline double getLikelihood() const { return emObj.isTrained() ? likelihood : DBL_MAX; }
#endif #endif
......
...@@ -41,6 +41,8 @@ ...@@ -41,6 +41,8 @@
#include "precomp.hpp" #include "precomp.hpp"
using namespace cv;
CvEMParams::CvEMParams() : nclusters(10), cov_mat_type(CvEM::COV_MAT_DIAGONAL), CvEMParams::CvEMParams() : nclusters(10), cov_mat_type(CvEM::COV_MAT_DIAGONAL),
start_step(CvEM::START_AUTO_STEP), probs(0), weights(0), means(0), covs(0) start_step(CvEM::START_AUTO_STEP), probs(0), weights(0), means(0), covs(0)
{ {
...@@ -76,38 +78,44 @@ void CvEM::clear() ...@@ -76,38 +78,44 @@ void CvEM::clear()
void CvEM::read( CvFileStorage* fs, CvFileNode* node ) void CvEM::read( CvFileStorage* fs, CvFileNode* node )
{ {
cv::FileNode fn(fs, node); FileNode fn(fs, node);
emObj.read(fn); emObj.read(fn);
set_mat_hdrs(); set_mat_hdrs();
} }
void CvEM::write( CvFileStorage* _fs, const char* name ) const void CvEM::write( CvFileStorage* _fs, const char* name ) const
{ {
cv::FileStorage fs = _fs; FileStorage fs = _fs;
if(name) if(name)
fs << name << "{"; fs << name << "{";
emObj.write(fs); emObj.write(fs);
if(name) if(name)
fs << "}"; fs << "}";
fs.fs.obj = 0;
} }
double CvEM::calcLikelihood( const cv::Mat &input_sample ) const double CvEM::calcLikelihood( const Mat &input_sample ) const
{ {
double likelihood; double likelihood;
emObj.predict(input_sample, 0, &likelihood); emObj.predict(input_sample, noArray(), &likelihood);
return likelihood; return likelihood;
} }
float float
CvEM::predict( const CvMat* _sample, CvMat* _probs, bool isNormalize ) const CvEM::predict( const CvMat* _sample, CvMat* _probs, bool isNormalize ) const
{ {
cv::Mat prbs; Mat prbs0 = cvarrToMat(_probs), prbs = prbs0, sample = cvarrToMat(_sample);
int cls = emObj.predict(_sample, _probs ? &prbs : 0); int cls = emObj.predict(sample, _probs ? _OutputArray(prbs) : _OutputArray::_OutputArray());
if(_probs) if(_probs)
{ {
if(isNormalize) if(isNormalize)
cv::normalize(prbs, prbs, 1, 0, cv::NORM_L1); normalize(prbs, prbs, 1, 0, NORM_L1);
*_probs = prbs;
if( prbs.data != prbs0.data )
{
CV_Assert( prbs.size == prbs0.size );
prbs.convertTo(prbs0, prbs0.type());
}
} }
return (float)cls; return (float)cls;
} }
...@@ -116,73 +124,55 @@ void CvEM::set_mat_hdrs() ...@@ -116,73 +124,55 @@ void CvEM::set_mat_hdrs()
{ {
if(emObj.isTrained()) if(emObj.isTrained())
{ {
meansHdr = emObj.getMeans(); meansHdr = emObj.get<Mat>("means");
covsHdrs.resize(emObj.getNClusters()); int K = emObj.get<int>("nclusters");
covsPtrs.resize(emObj.getNClusters()); covsHdrs.resize(K);
const std::vector<cv::Mat>& covs = emObj.getCovs(); covsPtrs.resize(K);
const std::vector<Mat>& covs = emObj.get<vector<Mat> >("covs");
for(size_t i = 0; i < covsHdrs.size(); i++) for(size_t i = 0; i < covsHdrs.size(); i++)
{ {
covsHdrs[i] = covs[i]; covsHdrs[i] = covs[i];
covsPtrs[i] = &covsHdrs[i]; covsPtrs[i] = &covsHdrs[i];
} }
weightsHdr = emObj.getWeights(); weightsHdr = emObj.get<Mat>("weights");
probsHdr = probs; probsHdr = probs;
} }
} }
static static
void init_params(const CvEMParams& src, cv::EM::Params& dst, void init_params(const CvEMParams& src,
cv::Mat& prbs, cv::Mat& weights, Mat& prbs, Mat& weights,
cv::Mat& means, cv::vector<cv::Mat>& covsHdrs) Mat& means, vector<Mat>& covsHdrs)
{ {
dst.nclusters = src.nclusters;
dst.covMatType = src.cov_mat_type;
dst.startStep = src.start_step;
dst.termCrit = src.term_crit;
prbs = src.probs; prbs = src.probs;
dst.probs = &prbs;
weights = src.weights; weights = src.weights;
dst.weights = &weights;
means = src.means; means = src.means;
dst.means = &means;
if(src.covs) if(src.covs)
{ {
covsHdrs.resize(src.nclusters); covsHdrs.resize(src.nclusters);
for(size_t i = 0; i < covsHdrs.size(); i++) for(size_t i = 0; i < covsHdrs.size(); i++)
covsHdrs[i] = src.covs[i]; covsHdrs[i] = src.covs[i];
dst.covs = &covsHdrs;
} }
} }
bool CvEM::train( const CvMat* _samples, const CvMat* _sample_idx, bool CvEM::train( const CvMat* _samples, const CvMat* _sample_idx,
CvEMParams _params, CvMat* _labels ) CvEMParams _params, CvMat* _labels )
{ {
cv::EM::Params params; CV_Assert(_sample_idx == 0);
cv::Mat prbs, weights, means; Mat samples = cvarrToMat(_samples), labels0, labels;
std::vector<cv::Mat> covsHdrs; if( _labels )
init_params(_params, params, prbs, weights, means, covsHdrs); labels0 = labels = cvarrToMat(_labels);
cv::Mat lbls; bool isOk = train(samples, Mat(), _params, _labels ? &labels : 0);
cv::Mat likelihoods; CV_Assert( labels0.data == labels.data );
bool isOk = emObj.train(_samples, _sample_idx, params, _labels ? &lbls : 0, &probs, &likelihoods );
if(isOk)
{
if(_labels)
*_labels = lbls;
likelihood = cv::sum(likelihoods)[0];
set_mat_hdrs();
}
return isOk; return isOk;
} }
int CvEM::get_nclusters() const int CvEM::get_nclusters() const
{ {
return emObj.getNClusters(); return emObj.get<int>("nclusters");
} }
const CvMat* CvEM::get_means() const const CvMat* CvEM::get_means() const
...@@ -215,16 +205,29 @@ CvEM::CvEM( const Mat& samples, const Mat& sample_idx, CvEMParams params ) ...@@ -215,16 +205,29 @@ CvEM::CvEM( const Mat& samples, const Mat& sample_idx, CvEMParams params )
bool CvEM::train( const Mat& _samples, const Mat& _sample_idx, bool CvEM::train( const Mat& _samples, const Mat& _sample_idx,
CvEMParams _params, Mat* _labels ) CvEMParams _params, Mat* _labels )
{ {
cv::EM::Params params; Mat prbs, weights, means, likelihoods;
cv::Mat prbs, weights, means; std::vector<Mat> covsHdrs;
std::vector<cv::Mat> covsHdrs; init_params(_params, prbs, weights, means, covsHdrs);
init_params(_params, params, prbs, weights, means, covsHdrs);
emObj = EM(_params.nclusters, _params.cov_mat_type, _params.term_crit);
cv::Mat likelihoods; bool isOk = false;
bool isOk = emObj.train(_samples, _sample_idx, params, _labels, &probs, &likelihoods); if( _params.start_step == EM::START_AUTO_STEP )
isOk = emObj.train(_samples, _labels ? _OutputArray(*_labels) : _OutputArray::_OutputArray(),
probs, likelihoods);
else if( _params.start_step == EM::START_E_STEP )
isOk = emObj.trainE(_samples, means, covsHdrs, weights,
_labels ? _OutputArray(*_labels) : _OutputArray::_OutputArray(),
probs, likelihoods);
else if( _params.start_step == EM::START_M_STEP )
isOk = emObj.trainM(_samples, prbs,
_labels ? _OutputArray(*_labels) : _OutputArray::_OutputArray(),
probs, likelihoods);
else
CV_Error(CV_StsBadArg, "Bad start type of EM algorithm");
if(isOk) if(isOk)
{ {
likelihoods = cv::sum(likelihoods).val[0]; likelihoods = sum(likelihoods).val[0];
set_mat_hdrs(); set_mat_hdrs();
} }
...@@ -234,34 +237,34 @@ bool CvEM::train( const Mat& _samples, const Mat& _sample_idx, ...@@ -234,34 +237,34 @@ bool CvEM::train( const Mat& _samples, const Mat& _sample_idx,
float float
CvEM::predict( const Mat& _sample, Mat* _probs, bool isNormalize ) const CvEM::predict( const Mat& _sample, Mat* _probs, bool isNormalize ) const
{ {
int cls = emObj.predict(_sample, _probs); int cls = emObj.predict(_sample, _probs ? _OutputArray(*_probs) : _OutputArray::_OutputArray());
if(_probs && isNormalize) if(_probs && isNormalize)
cv::normalize(*_probs, *_probs, 1, 0, cv::NORM_L1); normalize(*_probs, *_probs, 1, 0, NORM_L1);
return (float)cls; return (float)cls;
} }
int CvEM::getNClusters() const int CvEM::getNClusters() const
{ {
return emObj.getNClusters(); return emObj.get<int>("nclusters");
} }
const Mat& CvEM::getMeans() const Mat CvEM::getMeans() const
{ {
return emObj.getMeans(); return emObj.get<Mat>("means");
} }
void CvEM::getCovs(vector<Mat>& _covs) const void CvEM::getCovs(vector<Mat>& _covs) const
{ {
_covs = emObj.getCovs(); _covs = emObj.get<vector<Mat> >("covs");
} }
const Mat& CvEM::getWeights() const Mat CvEM::getWeights() const
{ {
return emObj.getWeights(); return emObj.get<Mat>("weights");
} }
const Mat& CvEM::getProbs() const Mat CvEM::getProbs() const
{ {
return probs; return probs;
} }
......
...@@ -371,19 +371,20 @@ protected: ...@@ -371,19 +371,20 @@ protected:
virtual void run( int /*start_from*/ ) virtual void run( int /*start_from*/ )
{ {
int code = cvtest::TS::OK; int code = cvtest::TS::OK;
cv::EM em;
Mat samples = Mat(3,1,CV_32F); Mat samples = Mat(3,1,CV_32F);
samples.at<float>(0,0) = 1; samples.at<float>(0,0) = 1;
samples.at<float>(1,0) = 2; samples.at<float>(1,0) = 2;
samples.at<float>(2,0) = 3; samples.at<float>(2,0) = 3;
Mat labels(samples.rows, 1, CV_32S);
cv::EM::Params params; CvEMParams params;
params.nclusters = 2; params.nclusters = 2;
Mat labels; CvMat samples_c = samples, labels_c = labels;
em.train(samples, Mat(), params, &labels); CvEM em(&samples_c, 0, params, &labels_c);
Mat firstResult(samples.rows, 1, CV_32FC1); Mat firstResult(samples.rows, 1, CV_32FC1);
for( int i = 0; i < samples.rows; i++) for( int i = 0; i < samples.rows; i++)
...@@ -396,9 +397,7 @@ protected: ...@@ -396,9 +397,7 @@ protected:
FileStorage fs = FileStorage(filename, FileStorage::WRITE); FileStorage fs = FileStorage(filename, FileStorage::WRITE);
try try
{ {
fs << "em" << "{"; em.write(fs.fs, "em");
em.write(fs);
fs << "}";
} }
catch(...) catch(...)
{ {
...@@ -416,7 +415,7 @@ protected: ...@@ -416,7 +415,7 @@ protected:
FileNode fn = fs["em"]; FileNode fn = fs["em"];
try try
{ {
em.read(fn); em.read(fs.fs, (CvFileNode*)fn.node);
} }
catch(...) catch(...)
{ {
......
...@@ -555,61 +555,66 @@ protected: ...@@ -555,61 +555,66 @@ protected:
\****************************************************************************************/ \****************************************************************************************/
namespace cv namespace cv
{ {
class CV_EXPORTS EM : public Algorithm class CV_EXPORTS_W EM : public Algorithm
{ {
public: public:
// Type of covariation matrices // Type of covariation matrices
enum {COV_MAT_SPHERICAL=0, COV_MAT_DIAGONAL=1, COV_MAT_GENERIC=2}; enum {COV_MAT_SPHERICAL=0, COV_MAT_DIAGONAL=1, COV_MAT_GENERIC=2, COV_MAT_DEFAULT=COV_MAT_DIAGONAL};
// Default parameters
enum {DEFAULT_NCLUSTERS=10, DEFAULT_MAX_ITERS=100};
// The initial step // The initial step
enum {START_E_STEP=1, START_M_STEP=2, START_AUTO_STEP=0}; enum {START_E_STEP=1, START_M_STEP=2, START_AUTO_STEP=0};
class CV_EXPORTS Params CV_WRAP EM(int nclusters=EM::DEFAULT_NCLUSTERS, int covMatType=EM::COV_MAT_DIAGONAL,
{ const TermCriteria& termcrit=TermCriteria(TermCriteria::COUNT+
public: TermCriteria::EPS,
Params(int nclusters=10, int covMatType=EM::COV_MAT_DIAGONAL, int startStep=EM::START_AUTO_STEP, EM::DEFAULT_MAX_ITERS, FLT_EPSILON));
const cv::TermCriteria& termCrit=cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, FLT_EPSILON),
const cv::Mat* probs=0, const cv::Mat* weights=0,
const cv::Mat* means=0, const std::vector<cv::Mat>* covs=0);
int nclusters;
int covMatType;
int startStep;
// all 4 following matrices should have type CV_32FC1
const cv::Mat* probs;
const cv::Mat* weights;
const cv::Mat* means;
const std::vector<cv::Mat>* covs;
cv::TermCriteria termCrit;
};
EM();
EM(const cv::Mat& samples, const cv::Mat samplesMask=cv::Mat(),
const EM::Params& params=EM::Params(), cv::Mat* labels=0, cv::Mat* probs=0, cv::Mat* likelihoods=0);
virtual ~EM(); virtual ~EM();
virtual void clear(); CV_WRAP virtual void clear();
virtual bool train(const cv::Mat& samples, const cv::Mat& samplesMask=cv::Mat(),
const EM::Params& params=EM::Params(), cv::Mat* labels=0, cv::Mat* probs=0, cv::Mat* likelihoods=0);
int predict(const cv::Mat& sample, cv::Mat* probs=0, double* likelihood=0) const;
bool isTrained() const; CV_WRAP virtual bool train(InputArray samples,
int getNClusters() const; OutputArray labels=noArray(),
int getCovMatType() const; OutputArray probs=noArray(),
OutputArray likelihoods=noArray());
CV_WRAP virtual bool trainE(InputArray samples,
InputArray means0,
InputArray covs0=noArray(),
InputArray weights0=noArray(),
OutputArray labels=noArray(),
OutputArray probs=noArray(),
OutputArray likelihoods=noArray());
CV_WRAP virtual bool trainM(InputArray samples,
InputArray probs0,
OutputArray labels=noArray(),
OutputArray probs=noArray(),
OutputArray likelihoods=noArray());
CV_WRAP int predict(InputArray sample,
OutputArray probs=noArray(),
CV_OUT double* likelihood=0) const;
const cv::Mat& getWeights() const; CV_WRAP bool isTrained() const;
const cv::Mat& getMeans() const;
const std::vector<cv::Mat>& getCovs() const;
AlgorithmInfo* info() const; AlgorithmInfo* info() const;
virtual void read(const FileNode& fn); virtual void read(const FileNode& fn);
protected: protected:
virtual void setTrainData(const cv::Mat& samples, const cv::Mat& samplesMask, const EM::Params& params);
virtual void setTrainData(int startStep, const Mat& samples,
bool doTrain(const cv::TermCriteria& termCrit); const Mat* probs0,
const Mat* means0,
const vector<Mat>* covs0,
const Mat* weights0);
bool doTrain(int startStep,
OutputArray labels,
OutputArray probs,
OutputArray likelihoods);
virtual void eStep(); virtual void eStep();
virtual void mStep(); virtual void mStep();
...@@ -617,27 +622,28 @@ protected: ...@@ -617,27 +622,28 @@ protected:
void decomposeCovs(); void decomposeCovs();
void computeLogWeightDivDet(); void computeLogWeightDivDet();
void computeProbabilities(const cv::Mat& sample, int& label, cv::Mat* probs, float* likelihood) const; void computeProbabilities(const Mat& sample, int& label, Mat* probs, float* likelihood) const;
// all inner matrices have type CV_32FC1 // all inner matrices have type CV_32FC1
int nclusters; CV_PROP_RW int nclusters;
int covMatType; CV_PROP_RW int covMatType;
int startStep; CV_PROP_RW int maxIters;
CV_PROP_RW double epsilon;
cv::Mat trainSamples;
cv::Mat trainProbs; Mat trainSamples;
cv::Mat trainLikelihoods; Mat trainProbs;
cv::Mat trainLabels; Mat trainLikelihoods;
cv::Mat trainCounts; Mat trainLabels;
Mat trainCounts;
cv::Mat weights;
cv::Mat means; CV_PROP Mat weights;
std::vector<cv::Mat> covs; CV_PROP Mat means;
CV_PROP vector<Mat> covs;
std::vector<cv::Mat> covsEigenValues;
std::vector<cv::Mat> covsRotateMats; vector<Mat> covsEigenValues;
std::vector<cv::Mat> invCovsEigenValues; vector<Mat> covsRotateMats;
cv::Mat logWeightDivDet; vector<Mat> invCovsEigenValues;
Mat logWeightDivDet;
}; };
} // namespace cv } // namespace cv
......
This diff is collapsed.
...@@ -320,6 +320,30 @@ void CV_KNearestTest::run( int /*start_from*/ ) ...@@ -320,6 +320,30 @@ void CV_KNearestTest::run( int /*start_from*/ )
ts->set_failed_test_info( code ); ts->set_failed_test_info( code );
} }
class EM_Params
{
public:
EM_Params(int nclusters=10, int covMatType=EM::COV_MAT_DIAGONAL, int startStep=EM::START_AUTO_STEP,
const cv::TermCriteria& termCrit=cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 100, FLT_EPSILON),
const cv::Mat* probs=0, const cv::Mat* weights=0,
const cv::Mat* means=0, const std::vector<cv::Mat>* covs=0)
: nclusters(nclusters), covMatType(covMatType), startStep(startStep),
probs(probs), weights(weights), means(means), covs(covs), termCrit(termCrit)
{}
int nclusters;
int covMatType;
int startStep;
// all 4 following matrices should have type CV_32FC1
const cv::Mat* probs;
const cv::Mat* weights;
const cv::Mat* means;
const std::vector<cv::Mat>* covs;
cv::TermCriteria termCrit;
};
//-------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------
class CV_EMTest : public cvtest::BaseTest class CV_EMTest : public cvtest::BaseTest
{ {
...@@ -327,13 +351,13 @@ public: ...@@ -327,13 +351,13 @@ public:
CV_EMTest() {} CV_EMTest() {}
protected: protected:
virtual void run( int start_from ); virtual void run( int start_from );
int runCase( int caseIndex, const cv::EM::Params& params, int runCase( int caseIndex, const EM_Params& params,
const cv::Mat& trainData, const cv::Mat& trainLabels, const cv::Mat& trainData, const cv::Mat& trainLabels,
const cv::Mat& testData, const cv::Mat& testLabels, const cv::Mat& testData, const cv::Mat& testLabels,
const vector<int>& sizes); const vector<int>& sizes);
}; };
int CV_EMTest::runCase( int caseIndex, const cv::EM::Params& params, int CV_EMTest::runCase( int caseIndex, const EM_Params& params,
const cv::Mat& trainData, const cv::Mat& trainLabels, const cv::Mat& trainData, const cv::Mat& trainLabels,
const cv::Mat& testData, const cv::Mat& testLabels, const cv::Mat& testData, const cv::Mat& testLabels,
const vector<int>& sizes ) const vector<int>& sizes )
...@@ -343,8 +367,13 @@ int CV_EMTest::runCase( int caseIndex, const cv::EM::Params& params, ...@@ -343,8 +367,13 @@ int CV_EMTest::runCase( int caseIndex, const cv::EM::Params& params,
cv::Mat labels; cv::Mat labels;
float err; float err;
cv::EM em; cv::EM em(params.nclusters, params.covMatType, params.termCrit);
em.train( trainData, Mat(), params, &labels ); if( params.startStep == EM::START_AUTO_STEP )
em.train( trainData, labels );
else if( params.startStep == EM::START_E_STEP )
em.trainE( trainData, *params.means, *params.covs, *params.weights, labels );
else if( params.startStep == EM::START_M_STEP )
em.trainM( trainData, *params.probs, labels );
// check train error // check train error
if( !calcErr( labels, trainLabels, sizes, err , false ) ) if( !calcErr( labels, trainLabels, sizes, err , false ) )
...@@ -363,7 +392,7 @@ int CV_EMTest::runCase( int caseIndex, const cv::EM::Params& params, ...@@ -363,7 +392,7 @@ int CV_EMTest::runCase( int caseIndex, const cv::EM::Params& params,
for( int i = 0; i < testData.rows; i++ ) for( int i = 0; i < testData.rows; i++ )
{ {
Mat sample = testData.row(i); Mat sample = testData.row(i);
labels.at<int>(i,0) = (int)em.predict( sample, 0 ); labels.at<int>(i,0) = (int)em.predict( sample, noArray() );
} }
if( !calcErr( labels, testLabels, sizes, err, false ) ) if( !calcErr( labels, testLabels, sizes, err, false ) )
{ {
...@@ -398,7 +427,7 @@ void CV_EMTest::run( int /*start_from*/ ) ...@@ -398,7 +427,7 @@ void CV_EMTest::run( int /*start_from*/ )
Mat testData( pointsCount, 2, CV_32FC1 ), testLabels; Mat testData( pointsCount, 2, CV_32FC1 ), testLabels;
generateData( testData, testLabels, sizes, means, covs, CV_32SC1 ); generateData( testData, testLabels, sizes, means, covs, CV_32SC1 );
cv::EM::Params params; EM_Params params;
params.nclusters = 3; params.nclusters = 3;
Mat probs(trainData.rows, params.nclusters, CV_32FC1, cv::Scalar(1)); Mat probs(trainData.rows, params.nclusters, CV_32FC1, cv::Scalar(1));
params.probs = &probs; params.probs = &probs;
...@@ -474,19 +503,16 @@ protected: ...@@ -474,19 +503,16 @@ protected:
virtual void run( int /*start_from*/ ) virtual void run( int /*start_from*/ )
{ {
int code = cvtest::TS::OK; int code = cvtest::TS::OK;
cv::EM em; cv::EM em(2);
Mat samples = Mat(3,1,CV_32F); Mat samples = Mat(3,1,CV_32F);
samples.at<float>(0,0) = 1; samples.at<float>(0,0) = 1;
samples.at<float>(1,0) = 2; samples.at<float>(1,0) = 2;
samples.at<float>(2,0) = 3; samples.at<float>(2,0) = 3;
cv::EM::Params params;
params.nclusters = 2;
Mat labels; Mat labels;
em.train(samples, Mat(), params, &labels); em.train(samples, labels);
Mat firstResult(samples.rows, 1, CV_32FC1); Mat firstResult(samples.rows, 1, CV_32FC1);
for( int i = 0; i < samples.rows; i++) for( int i = 0; i < samples.rows; i++)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment