}
//--------------------------------------------------------------------------------
-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();
- ml::KDTree* tr;
-};
-
-
-void CV_KDTreeTest_CPP::createModel( const Mat& data )
-{
- tr = new ml::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
{
public:
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(); }
static Ptr<ANN_MLP> create(const Params& params=Params());
};
-/*!
- 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
-};
-
/****************************************************************************************\
* Auxilary functions declarations *
\****************************************************************************************/
//M*/
#include "precomp.hpp"
+#include "kdtree.hpp"
namespace cv
{
--- /dev/null
+#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
//M*/
#include "precomp.hpp"
+#include "kdtree.hpp"
/****************************************************************************************\
* K-Nearest Neighbors Classifier *
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 );
}