Merge pull request #3126 from avdmitry:move_KDTree_to_ml
This commit is contained in:
commit
4057e27539
@ -747,93 +747,6 @@ public:
|
||||
int minusStep, plusStep;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Fast Nearest Neighbor Search Class.
|
||||
|
||||
The class implements D. Lowe BBF (Best-Bin-First) algorithm for the last
|
||||
approximate (or accurate) nearest neighbor search in multi-dimensional spaces.
|
||||
|
||||
First, a set of vectors is passed to KDTree::KDTree() constructor
|
||||
or KDTree::build() method, where it is reordered.
|
||||
|
||||
Then arbitrary vectors can be passed to KDTree::findNearest() methods, which
|
||||
find the K nearest neighbors among the vectors from the initial set.
|
||||
The user can balance between the speed and accuracy of the search by varying Emax
|
||||
parameter, which is the number of leaves that the algorithm checks.
|
||||
The larger parameter values yield more accurate results at the expense of lower processing speed.
|
||||
|
||||
\code
|
||||
KDTree T(points, false);
|
||||
const int K = 3, Emax = INT_MAX;
|
||||
int idx[K];
|
||||
float dist[K];
|
||||
T.findNearest(query_vec, K, Emax, idx, 0, dist);
|
||||
CV_Assert(dist[0] <= dist[1] && dist[1] <= dist[2]);
|
||||
\endcode
|
||||
*/
|
||||
class CV_EXPORTS_W KDTree
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
The node of the search tree.
|
||||
*/
|
||||
struct Node
|
||||
{
|
||||
Node() : idx(-1), left(-1), right(-1), boundary(0.f) {}
|
||||
Node(int _idx, int _left, int _right, float _boundary)
|
||||
: idx(_idx), left(_left), right(_right), boundary(_boundary) {}
|
||||
|
||||
//! split dimension; >=0 for nodes (dim), < 0 for leaves (index of the point)
|
||||
int idx;
|
||||
//! node indices of the left and the right branches
|
||||
int left, right;
|
||||
//! go to the left if query_vec[node.idx]<=node.boundary, otherwise go to the right
|
||||
float boundary;
|
||||
};
|
||||
|
||||
//! the default constructor
|
||||
CV_WRAP KDTree();
|
||||
//! the full constructor that builds the search tree
|
||||
CV_WRAP KDTree(InputArray points, bool copyAndReorderPoints = false);
|
||||
//! the full constructor that builds the search tree
|
||||
CV_WRAP KDTree(InputArray points, InputArray _labels,
|
||||
bool copyAndReorderPoints = false);
|
||||
//! builds the search tree
|
||||
CV_WRAP void build(InputArray points, bool copyAndReorderPoints = false);
|
||||
//! builds the search tree
|
||||
CV_WRAP void build(InputArray points, InputArray labels,
|
||||
bool copyAndReorderPoints = false);
|
||||
//! finds the K nearest neighbors of "vec" while looking at Emax (at most) leaves
|
||||
CV_WRAP int findNearest(InputArray vec, int K, int Emax,
|
||||
OutputArray neighborsIdx,
|
||||
OutputArray neighbors = noArray(),
|
||||
OutputArray dist = noArray(),
|
||||
OutputArray labels = noArray()) const;
|
||||
//! finds all the points from the initial set that belong to the specified box
|
||||
CV_WRAP void findOrthoRange(InputArray minBounds,
|
||||
InputArray maxBounds,
|
||||
OutputArray neighborsIdx,
|
||||
OutputArray neighbors = noArray(),
|
||||
OutputArray labels = noArray()) const;
|
||||
//! returns vectors with the specified indices
|
||||
CV_WRAP void getPoints(InputArray idx, OutputArray pts,
|
||||
OutputArray labels = noArray()) const;
|
||||
//! return a vector with the specified index
|
||||
const float* getPoint(int ptidx, int* label = 0) const;
|
||||
//! returns the search space dimensionality
|
||||
CV_WRAP int dims() const;
|
||||
|
||||
std::vector<Node> nodes; //!< all the tree nodes
|
||||
CV_PROP Mat points; //!< all the points. It can be a reordered copy of the input vector set or the original vector set.
|
||||
CV_PROP std::vector<int> labels; //!< the parallel array of labels.
|
||||
CV_PROP int maxDepth; //!< maximum depth of the search tree. Do not modify it
|
||||
CV_PROP_RW int normType; //!< type of the distance (cv::NORM_L1 or cv::NORM_L2) used for search. Initially set to cv::NORM_L2, but you can modify it
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
Random Number Generator
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
set(the_description "2D Features Framework")
|
||||
ocv_define_module(features2d opencv_imgproc opencv_flann OPTIONAL opencv_highgui)
|
||||
ocv_define_module(features2d opencv_imgproc opencv_ml opencv_flann OPTIONAL opencv_highgui)
|
||||
|
@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -156,91 +157,6 @@ void NearestNeighborTest::run( int /*start_from*/ ) {
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
class CV_KDTreeTest_CPP : public NearestNeighborTest
|
||||
{
|
||||
public:
|
||||
CV_KDTreeTest_CPP() {}
|
||||
protected:
|
||||
virtual void createModel( const Mat& data );
|
||||
virtual int checkGetPoins( const Mat& data );
|
||||
virtual int findNeighbors( Mat& points, Mat& neighbors );
|
||||
virtual int checkFindBoxed();
|
||||
virtual void releaseModel();
|
||||
KDTree* tr;
|
||||
};
|
||||
|
||||
|
||||
void CV_KDTreeTest_CPP::createModel( const Mat& data )
|
||||
{
|
||||
tr = new KDTree( data, false );
|
||||
}
|
||||
|
||||
int CV_KDTreeTest_CPP::checkGetPoins( const Mat& data )
|
||||
{
|
||||
Mat res1( data.size(), data.type() ),
|
||||
res3( data.size(), data.type() );
|
||||
Mat idxs( 1, data.rows, CV_32SC1 );
|
||||
for( int pi = 0; pi < data.rows; pi++ )
|
||||
{
|
||||
idxs.at<int>(0, pi) = pi;
|
||||
// 1st way
|
||||
const float* point = tr->getPoint(pi);
|
||||
for( int di = 0; di < data.cols; di++ )
|
||||
res1.at<float>(pi, di) = point[di];
|
||||
}
|
||||
|
||||
// 3d way
|
||||
tr->getPoints( idxs, res3 );
|
||||
|
||||
if( cvtest::norm( res1, data, NORM_L1) != 0 ||
|
||||
cvtest::norm( res3, data, NORM_L1) != 0)
|
||||
return cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
return cvtest::TS::OK;
|
||||
}
|
||||
|
||||
int CV_KDTreeTest_CPP::checkFindBoxed()
|
||||
{
|
||||
vector<float> min( dims, static_cast<float>(minValue)), max(dims, static_cast<float>(maxValue));
|
||||
vector<int> indices;
|
||||
tr->findOrthoRange( min, max, indices );
|
||||
// TODO check indices
|
||||
if( (int)indices.size() != featuresCount)
|
||||
return cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
return cvtest::TS::OK;
|
||||
}
|
||||
|
||||
int CV_KDTreeTest_CPP::findNeighbors( Mat& points, Mat& neighbors )
|
||||
{
|
||||
const int emax = 20;
|
||||
Mat neighbors2( neighbors.size(), CV_32SC1 );
|
||||
int j;
|
||||
for( int pi = 0; pi < points.rows; pi++ )
|
||||
{
|
||||
// 1st way
|
||||
Mat nrow = neighbors.row(pi);
|
||||
tr->findNearest( points.row(pi), neighbors.cols, emax, nrow );
|
||||
|
||||
// 2nd way
|
||||
vector<int> neighborsIdx2( neighbors2.cols, 0 );
|
||||
tr->findNearest( points.row(pi), neighbors2.cols, emax, neighborsIdx2 );
|
||||
vector<int>::const_iterator it2 = neighborsIdx2.begin();
|
||||
for( j = 0; it2 != neighborsIdx2.end(); ++it2, j++ )
|
||||
neighbors2.at<int>(pi,j) = *it2;
|
||||
}
|
||||
|
||||
// compare results
|
||||
if( cvtest::norm( neighbors, neighbors2, NORM_L1 ) != 0 )
|
||||
return cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
|
||||
return cvtest::TS::OK;
|
||||
}
|
||||
|
||||
void CV_KDTreeTest_CPP::releaseModel()
|
||||
{
|
||||
delete tr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
class CV_FlannTest : public NearestNeighborTest
|
||||
{
|
||||
@ -402,7 +318,6 @@ void CV_FlannSavedIndexTest::createModel(const cv::Mat &data)
|
||||
remove( filename.c_str() );
|
||||
}
|
||||
|
||||
TEST(Features2d_KDTree_CPP, regression) { CV_KDTreeTest_CPP test; test.safe_run(); }
|
||||
TEST(Features2d_FLANN_Linear, regression) { CV_FlannLinearIndexTest test; test.safe_run(); }
|
||||
TEST(Features2d_FLANN_KMeans, regression) { CV_FlannKMeansIndexTest test; test.safe_run(); }
|
||||
TEST(Features2d_FLANN_KDTree, regression) { CV_FlannKDTreeIndexTest test; test.safe_run(); }
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/features2d.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#include "opencv2/ml.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -228,10 +229,12 @@ public:
|
||||
class CV_EXPORTS_W_MAP Params
|
||||
{
|
||||
public:
|
||||
Params(int defaultK=10, bool isclassifier=true);
|
||||
Params(int defaultK=10, bool isclassifier_=true, int Emax_=INT_MAX, int algorithmType_=BRUTE_FORCE);
|
||||
|
||||
CV_PROP_RW int defaultK;
|
||||
CV_PROP_RW bool isclassifier;
|
||||
CV_PROP_RW int Emax; // for implementation with KDTree
|
||||
CV_PROP_RW int algorithmType;
|
||||
};
|
||||
virtual void setParams(const Params& p) = 0;
|
||||
virtual Params getParams() const = 0;
|
||||
@ -239,6 +242,9 @@ public:
|
||||
OutputArray results,
|
||||
OutputArray neighborResponses=noArray(),
|
||||
OutputArray dist=noArray() ) const = 0;
|
||||
|
||||
enum { BRUTE_FORCE=1, KDTREE=2 };
|
||||
|
||||
static Ptr<KNearest> create(const Params& params=Params());
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Copyright (C) 2014, Itseez Inc, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -42,13 +43,14 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "kdtree.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
namespace ml
|
||||
{
|
||||
// This is reimplementation of kd-trees from cvkdtree*.* by Xavier Delacour, cleaned-up and
|
||||
// adopted to work with the new OpenCV data structures. It's in cxcore to be shared by
|
||||
// both cv (CvFeatureTree) and ml (kNN).
|
||||
// adopted to work with the new OpenCV data structures.
|
||||
|
||||
// The algorithm is taken from:
|
||||
// J.S. Beis and D.G. Lowe. Shape indexing using approximate nearest-neighbor search
|
||||
@ -529,3 +531,4 @@ int KDTree::dims() const
|
||||
}
|
||||
|
||||
}
|
||||
}
|
97
modules/ml/src/kdtree.hpp
Normal file
97
modules/ml/src/kdtree.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef KDTREE_H
|
||||
#define KDTREE_H
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
namespace cv
|
||||
{
|
||||
namespace ml
|
||||
{
|
||||
|
||||
/*!
|
||||
Fast Nearest Neighbor Search Class.
|
||||
|
||||
The class implements D. Lowe BBF (Best-Bin-First) algorithm for the last
|
||||
approximate (or accurate) nearest neighbor search in multi-dimensional spaces.
|
||||
|
||||
First, a set of vectors is passed to KDTree::KDTree() constructor
|
||||
or KDTree::build() method, where it is reordered.
|
||||
|
||||
Then arbitrary vectors can be passed to KDTree::findNearest() methods, which
|
||||
find the K nearest neighbors among the vectors from the initial set.
|
||||
The user can balance between the speed and accuracy of the search by varying Emax
|
||||
parameter, which is the number of leaves that the algorithm checks.
|
||||
The larger parameter values yield more accurate results at the expense of lower processing speed.
|
||||
|
||||
\code
|
||||
KDTree T(points, false);
|
||||
const int K = 3, Emax = INT_MAX;
|
||||
int idx[K];
|
||||
float dist[K];
|
||||
T.findNearest(query_vec, K, Emax, idx, 0, dist);
|
||||
CV_Assert(dist[0] <= dist[1] && dist[1] <= dist[2]);
|
||||
\endcode
|
||||
*/
|
||||
class CV_EXPORTS_W KDTree
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
The node of the search tree.
|
||||
*/
|
||||
struct Node
|
||||
{
|
||||
Node() : idx(-1), left(-1), right(-1), boundary(0.f) {}
|
||||
Node(int _idx, int _left, int _right, float _boundary)
|
||||
: idx(_idx), left(_left), right(_right), boundary(_boundary) {}
|
||||
|
||||
//! split dimension; >=0 for nodes (dim), < 0 for leaves (index of the point)
|
||||
int idx;
|
||||
//! node indices of the left and the right branches
|
||||
int left, right;
|
||||
//! go to the left if query_vec[node.idx]<=node.boundary, otherwise go to the right
|
||||
float boundary;
|
||||
};
|
||||
|
||||
//! the default constructor
|
||||
CV_WRAP KDTree();
|
||||
//! the full constructor that builds the search tree
|
||||
CV_WRAP KDTree(InputArray points, bool copyAndReorderPoints = false);
|
||||
//! the full constructor that builds the search tree
|
||||
CV_WRAP KDTree(InputArray points, InputArray _labels,
|
||||
bool copyAndReorderPoints = false);
|
||||
//! builds the search tree
|
||||
CV_WRAP void build(InputArray points, bool copyAndReorderPoints = false);
|
||||
//! builds the search tree
|
||||
CV_WRAP void build(InputArray points, InputArray labels,
|
||||
bool copyAndReorderPoints = false);
|
||||
//! finds the K nearest neighbors of "vec" while looking at Emax (at most) leaves
|
||||
CV_WRAP int findNearest(InputArray vec, int K, int Emax,
|
||||
OutputArray neighborsIdx,
|
||||
OutputArray neighbors = noArray(),
|
||||
OutputArray dist = noArray(),
|
||||
OutputArray labels = noArray()) const;
|
||||
//! finds all the points from the initial set that belong to the specified box
|
||||
CV_WRAP void findOrthoRange(InputArray minBounds,
|
||||
InputArray maxBounds,
|
||||
OutputArray neighborsIdx,
|
||||
OutputArray neighbors = noArray(),
|
||||
OutputArray labels = noArray()) const;
|
||||
//! returns vectors with the specified indices
|
||||
CV_WRAP void getPoints(InputArray idx, OutputArray pts,
|
||||
OutputArray labels = noArray()) const;
|
||||
//! return a vector with the specified index
|
||||
const float* getPoint(int ptidx, int* label = 0) const;
|
||||
//! returns the search space dimensionality
|
||||
CV_WRAP int dims() const;
|
||||
|
||||
std::vector<Node> nodes; //!< all the tree nodes
|
||||
CV_PROP Mat points; //!< all the points. It can be a reordered copy of the input vector set or the original vector set.
|
||||
CV_PROP std::vector<int> labels; //!< the parallel array of labels.
|
||||
CV_PROP int maxDepth; //!< maximum depth of the search tree. Do not modify it
|
||||
CV_PROP_RW int normType; //!< type of the distance (cv::NORM_L1 or cv::NORM_L2) used for search. Initially set to cv::NORM_L2, but you can modify it
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -41,6 +41,7 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "kdtree.hpp"
|
||||
|
||||
/****************************************************************************************\
|
||||
* K-Nearest Neighbors Classifier *
|
||||
@ -49,13 +50,14 @@
|
||||
namespace cv {
|
||||
namespace ml {
|
||||
|
||||
KNearest::Params::Params(int k, bool isclassifier_)
|
||||
KNearest::Params::Params(int k, bool isclassifier_, int Emax_, int algorithmType_) :
|
||||
defaultK(k),
|
||||
isclassifier(isclassifier_),
|
||||
Emax(Emax_),
|
||||
algorithmType(algorithmType_)
|
||||
{
|
||||
defaultK = k;
|
||||
isclassifier = isclassifier_;
|
||||
}
|
||||
|
||||
|
||||
class KNearestImpl : public KNearest
|
||||
{
|
||||
public:
|
||||
@ -352,8 +354,156 @@ public:
|
||||
Params params;
|
||||
};
|
||||
|
||||
|
||||
class KNearestKDTreeImpl : public KNearest
|
||||
{
|
||||
public:
|
||||
KNearestKDTreeImpl(const Params& p)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
float findNearest( InputArray _samples, int k,
|
||||
OutputArray _results,
|
||||
OutputArray _neighborResponses,
|
||||
OutputArray _dists ) const
|
||||
{
|
||||
float result = 0.f;
|
||||
CV_Assert( 0 < k );
|
||||
|
||||
Mat test_samples = _samples.getMat();
|
||||
CV_Assert( test_samples.type() == CV_32F && test_samples.cols == samples.cols );
|
||||
int testcount = test_samples.rows;
|
||||
|
||||
if( testcount == 0 )
|
||||
{
|
||||
_results.release();
|
||||
_neighborResponses.release();
|
||||
_dists.release();
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
Mat res, nr, d;
|
||||
if( _results.needed() )
|
||||
{
|
||||
_results.create(testcount, 1, CV_32F);
|
||||
res = _results.getMat();
|
||||
}
|
||||
if( _neighborResponses.needed() )
|
||||
{
|
||||
_neighborResponses.create(testcount, k, CV_32F);
|
||||
nr = _neighborResponses.getMat();
|
||||
}
|
||||
if( _dists.needed() )
|
||||
{
|
||||
_dists.create(testcount, k, CV_32F);
|
||||
d = _dists.getMat();
|
||||
}
|
||||
|
||||
for (int i=0; i<test_samples.rows; ++i)
|
||||
{
|
||||
Mat _res, _nr, _d;
|
||||
if (res.rows>i)
|
||||
{
|
||||
_res = res.row(i);
|
||||
}
|
||||
if (nr.rows>i)
|
||||
{
|
||||
_nr = nr.row(i);
|
||||
}
|
||||
if (d.rows>i)
|
||||
{
|
||||
_d = d.row(i);
|
||||
}
|
||||
tr.findNearest(test_samples.row(i), k, params.Emax, _res, _nr, _d, noArray());
|
||||
}
|
||||
|
||||
return result; // currently always 0
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
KDTree tr;
|
||||
|
||||
Mat samples;
|
||||
Mat responses;
|
||||
Params params;
|
||||
};
|
||||
|
||||
Ptr<KNearest> KNearest::create(const Params& p)
|
||||
{
|
||||
if (KDTREE==p.algorithmType)
|
||||
{
|
||||
return makePtr<KNearestKDTreeImpl>(p);
|
||||
}
|
||||
|
||||
return makePtr<KNearestImpl>(p);
|
||||
}
|
||||
|
||||
|
@ -312,9 +312,11 @@ void CV_KNearestTest::run( int /*start_from*/ )
|
||||
generateData( testData, testLabels, sizes, means, covs, CV_32FC1, CV_32FC1 );
|
||||
|
||||
int code = cvtest::TS::OK;
|
||||
Ptr<KNearest> knearest = KNearest::create(true);
|
||||
knearest->train(trainData, cv::ml::ROW_SAMPLE, trainLabels);
|
||||
knearest->findNearest( testData, 4, bestLabels);
|
||||
|
||||
// KNearest default implementation
|
||||
Ptr<KNearest> knearest = KNearest::create();
|
||||
knearest->train(trainData, ml::ROW_SAMPLE, trainLabels);
|
||||
knearest->findNearest(testData, 4, bestLabels);
|
||||
float err;
|
||||
if( !calcErr( bestLabels, testLabels, sizes, err, true ) )
|
||||
{
|
||||
@ -326,6 +328,22 @@ void CV_KNearestTest::run( int /*start_from*/ )
|
||||
ts->printf( cvtest::TS::LOG, "Bad accuracy (%f) on test data.\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
}
|
||||
|
||||
// KNearest KDTree implementation
|
||||
Ptr<KNearest> knearestKdt = KNearest::create(ml::KNearest::Params(10, true, INT_MAX, ml::KNearest::KDTREE));
|
||||
knearestKdt->train(trainData, ml::ROW_SAMPLE, trainLabels);
|
||||
knearestKdt->findNearest(testData, 4, bestLabels);
|
||||
if( !calcErr( bestLabels, testLabels, sizes, err, true ) )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Bad output labels.\n" );
|
||||
code = cvtest::TS::FAIL_INVALID_OUTPUT;
|
||||
}
|
||||
else if( err > 0.01f )
|
||||
{
|
||||
ts->printf( cvtest::TS::LOG, "Bad accuracy (%f) on test data.\n", err );
|
||||
code = cvtest::TS::FAIL_BAD_ACCURACY;
|
||||
}
|
||||
|
||||
ts->set_failed_test_info( code );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user