1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Updated ml module interfaces and documentation

This commit is contained in:
Maksim Shabunin
2015-02-11 13:24:14 +03:00
parent da383e65e2
commit 79e8f0680c
32 changed files with 1403 additions and 1528 deletions
+139 -132
View File
@@ -50,46 +50,33 @@
namespace cv {
namespace ml {
KNearest::Params::Params(int k, bool isclassifier_, int Emax_, int algorithmType_) :
defaultK(k),
isclassifier(isclassifier_),
Emax(Emax_),
algorithmType(algorithmType_)
{
}
const String NAME_BRUTE_FORCE = "opencv_ml_knn";
const String NAME_KDTREE = "opencv_ml_knn_kd";
class KNearestImpl : public KNearest
class Impl
{
public:
KNearestImpl(const Params& p)
Impl()
{
params = p;
defaultK = 10;
isclassifier = true;
Emax = INT_MAX;
}
virtual ~KNearestImpl() {}
Params getParams() const { return params; }
void setParams(const Params& p) { params = p; }
bool isClassifier() const { return params.isclassifier; }
bool isTrained() const { return !samples.empty(); }
String getDefaultModelName() const { return "opencv_ml_knn"; }
void clear()
{
samples.release();
responses.release();
}
int getVarCount() const { return samples.cols; }
virtual ~Impl() {}
virtual String getModelName() const = 0;
virtual int getType() const = 0;
virtual float findNearest( InputArray _samples, int k,
OutputArray _results,
OutputArray _neighborResponses,
OutputArray _dists ) const = 0;
bool train( const Ptr<TrainData>& data, int flags )
{
Mat new_samples = data->getTrainSamples(ROW_SAMPLE);
Mat new_responses;
data->getTrainResponses().convertTo(new_responses, CV_32F);
bool update = (flags & UPDATE_MODEL) != 0 && !samples.empty();
bool update = (flags & ml::KNearest::UPDATE_MODEL) != 0 && !samples.empty();
CV_Assert( new_samples.type() == CV_32F );
@@ -106,9 +93,53 @@ public:
samples.push_back(new_samples);
responses.push_back(new_responses);
doTrain(samples);
return true;
}
virtual void doTrain(InputArray points) { (void)points; }
void clear()
{
samples.release();
responses.release();
}
void read( const FileNode& fn )
{
clear();
isclassifier = (int)fn["is_classifier"] != 0;
defaultK = (int)fn["default_k"];
fn["samples"] >> samples;
fn["responses"] >> responses;
}
void write( FileStorage& fs ) const
{
fs << "is_classifier" << (int)isclassifier;
fs << "default_k" << defaultK;
fs << "samples" << samples;
fs << "responses" << responses;
}
public:
int defaultK;
bool isclassifier;
int Emax;
Mat samples;
Mat responses;
};
class BruteForceImpl : public Impl
{
public:
String getModelName() const { return NAME_BRUTE_FORCE; }
int getType() const { return ml::KNearest::BRUTE_FORCE; }
void findNearestCore( const Mat& _samples, int k0, const Range& range,
Mat* results, Mat* neighbor_responses,
Mat* dists, float* presult ) const
@@ -199,7 +230,7 @@ public:
if( results || testidx+range.start == 0 )
{
if( !params.isclassifier || k == 1 )
if( !isclassifier || k == 1 )
{
float s = 0.f;
for( j = 0; j < k; j++ )
@@ -251,7 +282,7 @@ public:
struct findKNearestInvoker : public ParallelLoopBody
{
findKNearestInvoker(const KNearestImpl* _p, int _k, const Mat& __samples,
findKNearestInvoker(const BruteForceImpl* _p, int _k, const Mat& __samples,
Mat* __results, Mat* __neighbor_responses, Mat* __dists, float* _presult)
{
p = _p;
@@ -273,7 +304,7 @@ public:
}
}
const KNearestImpl* p;
const BruteForceImpl* p;
int k;
const Mat* _samples;
Mat* _results;
@@ -324,88 +355,18 @@ public:
//invoker(Range(0, testcount));
return result;
}
float predict(InputArray inputs, OutputArray outputs, int) const
{
return findNearest( inputs, params.defaultK, outputs, noArray(), noArray() );
}
void write( FileStorage& fs ) const
{
fs << "is_classifier" << (int)params.isclassifier;
fs << "default_k" << params.defaultK;
fs << "samples" << samples;
fs << "responses" << responses;
}
void read( const FileNode& fn )
{
clear();
params.isclassifier = (int)fn["is_classifier"] != 0;
params.defaultK = (int)fn["default_k"];
fn["samples"] >> samples;
fn["responses"] >> responses;
}
Mat samples;
Mat responses;
Params params;
};
class KNearestKDTreeImpl : public KNearest
class KDTreeImpl : public Impl
{
public:
KNearestKDTreeImpl(const Params& p)
String getModelName() const { return NAME_KDTREE; }
int getType() const { return ml::KNearest::KDTREE; }
void doTrain(InputArray points)
{
params = p;
}
virtual ~KNearestKDTreeImpl() {}
Params getParams() const { return params; }
void setParams(const Params& p) { params = p; }
bool isClassifier() const { return params.isclassifier; }
bool isTrained() const { return !samples.empty(); }
String getDefaultModelName() const { return "opencv_ml_knn_kd"; }
void clear()
{
samples.release();
responses.release();
}
int getVarCount() const { return samples.cols; }
bool train( const Ptr<TrainData>& data, int flags )
{
Mat new_samples = data->getTrainSamples(ROW_SAMPLE);
Mat new_responses;
data->getTrainResponses().convertTo(new_responses, CV_32F);
bool update = (flags & UPDATE_MODEL) != 0 && !samples.empty();
CV_Assert( new_samples.type() == CV_32F );
if( !update )
{
clear();
}
else
{
CV_Assert( new_samples.cols == samples.cols &&
new_responses.cols == responses.cols );
}
samples.push_back(new_samples);
responses.push_back(new_responses);
tr.build(samples);
return true;
tr.build(points);
}
float findNearest( InputArray _samples, int k,
@@ -460,51 +421,97 @@ public:
{
_d = d.row(i);
}
tr.findNearest(test_samples.row(i), k, params.Emax, _res, _nr, _d, noArray());
tr.findNearest(test_samples.row(i), k, Emax, _res, _nr, _d, noArray());
}
return result; // currently always 0
}
float predict(InputArray inputs, OutputArray outputs, int) const
KDTree tr;
};
//================================================================
class KNearestImpl : public KNearest
{
CV_IMPL_PROPERTY(int, DefaultK, impl->defaultK)
CV_IMPL_PROPERTY(bool, IsClassifier, impl->isclassifier)
CV_IMPL_PROPERTY(int, Emax, impl->Emax)
public:
int getAlgorithmType() const
{
return findNearest( inputs, params.defaultK, outputs, noArray(), noArray() );
return impl->getType();
}
void setAlgorithmType(int val)
{
if (val != BRUTE_FORCE && val != KDTREE)
val = BRUTE_FORCE;
initImpl(val);
}
public:
KNearestImpl()
{
initImpl(BRUTE_FORCE);
}
~KNearestImpl()
{
}
bool isClassifier() const { return impl->isclassifier; }
bool isTrained() const { return !impl->samples.empty(); }
int getVarCount() const { return impl->samples.cols; }
void write( FileStorage& fs ) const
{
fs << "is_classifier" << (int)params.isclassifier;
fs << "default_k" << params.defaultK;
fs << "samples" << samples;
fs << "responses" << responses;
impl->write(fs);
}
void read( const FileNode& fn )
{
clear();
params.isclassifier = (int)fn["is_classifier"] != 0;
params.defaultK = (int)fn["default_k"];
fn["samples"] >> samples;
fn["responses"] >> responses;
int algorithmType = BRUTE_FORCE;
if (fn.name() == NAME_KDTREE)
algorithmType = KDTREE;
initImpl(algorithmType);
impl->read(fn);
}
KDTree tr;
float findNearest( InputArray samples, int k,
OutputArray results,
OutputArray neighborResponses=noArray(),
OutputArray dist=noArray() ) const
{
return impl->findNearest(samples, k, results, neighborResponses, dist);
}
Mat samples;
Mat responses;
Params params;
float predict(InputArray inputs, OutputArray outputs, int) const
{
return impl->findNearest( inputs, impl->defaultK, outputs, noArray(), noArray() );
}
bool train( const Ptr<TrainData>& data, int flags )
{
return impl->train(data, flags);
}
String getDefaultModelName() const { return impl->getModelName(); }
protected:
void initImpl(int algorithmType)
{
if (algorithmType != KDTREE)
impl = makePtr<BruteForceImpl>();
else
impl = makePtr<KDTreeImpl>();
}
Ptr<Impl> impl;
};
Ptr<KNearest> KNearest::create(const Params& p)
Ptr<KNearest> KNearest::create()
{
if (KDTREE==p.algorithmType)
{
return makePtr<KNearestKDTreeImpl>(p);
}
return makePtr<KNearestImpl>(p);
return makePtr<KNearestImpl>();
}
}