У меня есть два набора двухмерных точек, набор А & B. В наборе A у меня 100 очков, а в наборе B — 5000 очков. Для каждой точки в наборе A я хочу найти ближайшего соседа или точку, ближайшую к нему из множества B. Я построил дерево kd OpenCV на множестве B и использовал точки множества A в качестве точек запроса.
Проблема в том, что для всех точек в множестве A Kd-дерево всегда возвращает 1-ю точку как ближайшую точку. Глядя на точки, я вижу, что есть другие точки, намного более близкие, чем 1-я точка множества B.
Вот некоторый код:
Mat matches; //This mat will contain the index of nearest neighbour as returned by Kd-tree
Mat distances; //In this mat Kd-Tree return the distances for each nearest neighbour
Mat ClusterMemebers; //This Set A
Mat ClusterCenters; //This set B
const cvflann::SearchParams params(32); //How many leaves to search in a tree
cv::flann::GenericIndex< cvflann::L2<int> > *kdtrees; // The flann searching tree
// Create matrices
ClusterCenters.create(cvSize(2,5000), CV_32S); // The set B
matches.create(cvSize(1,100), CV_32SC1);
distances.create(cvSize(1,100), CV_32FC1);
ClusterMembers.create(cvSize(2,100), CV_32S); // The set A
// After filling points in ClusterMembers (set A) and ClusterCenters (Set B)
// I create K-D tree
kdtrees = new flann::GenericIndex< cvflann::L2<int> >(ClusterCenters, vflann::KDTreeIndexParams(4)); // a 4 k-d tree
// Search KdTree
kdtrees->knnSearch(ClusterMembers, matches, distances, 1, cvflann::SearchParams(8));
int NN_index;
for(int l = 0; l < 100; l++)
{
NN_index = matches.at<float>(cvPoint(l, 0));
dist = distances.at<float>(cvPoint(l, 0));
}
NN_index
всегда 0, что означает 1-ю точку.
Вы забыли инициализировать ClusterMembers и ClusterCenters. Были и другие ошибки, так что вот рабочая версия вашего простого теста:
Mat matches; //This mat will contain the index of nearest neighbour as returned by Kd-tree
Mat distances; //In this mat Kd-Tree return the distances for each nearest neighbour
Mat ClusterMembers; //This Set A
Mat ClusterCenters; //This set B
const cvflann::SearchParams params(32); //How many leaves to search in a tree
cv::flann::GenericIndex< cvflann::L2<int> > *kdtrees; // The flann searching tree
// Create matrices
ClusterMembers.create(cvSize(2,100), CV_32S); // The set A
randu(ClusterMembers, Scalar::all(0), Scalar::all(1000));
ClusterCenters.create(cvSize(2,5000), CV_32S); // The set B
randu(ClusterCenters, Scalar::all(0), Scalar::all(1000));
matches.create(cvSize(1,100), CV_32SC1);
distances.create(cvSize(1,100), CV_32FC1);
kdtrees = new flann::GenericIndex< cvflann::L2<int> >(ClusterCenters, cvflann::KDTreeIndexParams(4)); // a 4 k-d tree
// Search KdTree
kdtrees->knnSearch(ClusterMembers, matches, distances, 1, cvflann::SearchParams(8));
int NN_index;
float dist;
for(int i = 0; i < 100; i++) {
NN_index = matches.at<int>(i,0);
dist = distances.at<float>(i, 0);
}
Боб Дэвис
Других решений пока нет …