42 template<
typename T,
typename CloudType>
47 data = load<T>(fileName);
58 struct Loader<T, Eigen::Map<const Eigen::Matrix<T, 3, Eigen::Dynamic>, Eigen::Aligned> >
62 data = load<T>(fileName);
64 Eigen::Map<const Eigen::Matrix<T, 3, Eigen::Dynamic>, Eigen::Aligned>
getValue()
const
66 return Eigen::Map<const Eigen::Matrix<T, 3, Eigen::Dynamic>, Eigen::Aligned>(data.data(), 3, data.cols());
70 Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>
data;
73 template<
typename T,
typename CloudType>
74 void validate(
const char *fileName,
const int K,
const int dim,
const int method,
const T maxRadius)
77 typedef vector<NNS*> NNSV;
78 typedef typename NNS::Matrix Matrix;
79 typedef typename NNS::Vector Vector;
80 typedef typename NNS::IndexMatrix IndexMatrix;
89 cerr <<
"Provided data has " <<
d.rows() <<
" dimensions, but the requested dimensions were " << dim << endl;
94 cerr <<
"Requested more nearest neighbour than points in the data set" << endl;
100 unsigned searchTypeCount(NNS::SEARCH_TYPE_COUNT);
102 searchTypeCount -= 3;
103 #endif // HAVE_OPENCL
104 for (
unsigned i = 0; i < searchTypeCount; ++i)
110 const int itCount(method != -1 ? method :
d.cols() * 2);
156 Matrix
q(createQuery<T>(
d, itCount, method));
157 IndexMatrix indexes_bf(K,
q.cols());
158 Matrix dists2_bf(K,
q.cols());
159 nnss[0]->knn(
q, indexes_bf, dists2_bf, K, 0, NNS::SORT_RESULTS, maxRadius);
160 assert(indexes_bf.cols() ==
q.cols());
161 for (
size_t j = 1; j < nnss.size(); ++j)
163 IndexMatrix indexes_kdtree(K,
q.cols());
164 Matrix dists2_kdtree(K,
q.cols());
165 nnss[j]->knn(
q, indexes_kdtree, dists2_kdtree, K, 0, NNS::SORT_RESULTS, maxRadius);
166 if (indexes_bf.rows() != K)
168 cerr <<
"Different number of points found between brute force and request" << endl;
171 if (indexes_bf.cols() != indexes_kdtree.cols())
173 cerr <<
"Different number of points found between brute force and NNS type "<< j << endl;
177 for (
int i = 0; i <
q.cols(); ++i)
179 for (
size_t k = 0; k < size_t(K); ++k)
181 if (dists2_bf(k,i) == NNS::InvalidValue)
183 const int pbfi(indexes_bf(k,i));
184 const Vector pbf(
d.col(pbfi));
185 const int pkdt(indexes_kdtree(k,i));
186 if (pkdt < 0 || pkdt >=
d.cols())
188 cerr <<
"Method " << j <<
", query point " << i <<
", neighbour " << k <<
" of " << K <<
" has invalid index " << pkdt <<
" out of range [0:" <<
d.cols() <<
"[" << endl;
191 const Vector pkdtree(
d.col(pkdt));
192 const Vector pq(
q.col(i));
193 const T distDiff(fabsf((pbf-pq).squaredNorm() - (pkdtree-pq).squaredNorm()));
194 if (distDiff > numeric_limits<T>::epsilon())
196 cerr <<
"Method " << j <<
", query point " << i <<
", neighbour " << k <<
" of " << K <<
" is different between bf and kdtree (dist2 " << distDiff <<
")\n";
197 cerr <<
"* query point:\n";
199 cerr <<
"* indexes " << pbfi <<
" (bf) vs " << pkdt <<
" (kdtree)\n";
200 cerr <<
"* coordinates:\n";
201 cerr <<
"bf: (dist " << (pbf-pq).norm() <<
")\n";
203 cerr <<
"kdtree (dist " << (pkdtree-pq).norm() <<
")\n";
204 cerr << pkdtree << endl;
205 cerr <<
"* bf neighbours:\n";
206 for (
int l = 0; l < K; ++l)
207 cerr << indexes_bf(l,i) <<
" (dist " << (
d.col(indexes_bf(l,i))-pq).norm() <<
")\n";
208 cerr <<
"* kdtree neighbours:\n";
209 for (
int l = 0; l < K; ++l)
210 cerr << indexes_kdtree(l,i) <<
" (dist " << (
d.col(indexes_kdtree(l,i))-pq).norm() <<
")\n";
224 for (
typename NNSV::iterator it(nnss.begin()); it != nnss.end(); ++it)
228 int main(
int argc,
char* argv[])
232 cerr <<
"Usage " << argv[0] <<
" DATA K DIM METHOD [MAX_RADIUS]" << endl;
236 const int K(atoi(argv[2]));
237 const int dim(atoi(argv[3]));
238 const int method(atoi(argv[4]));
239 const float maxRadius(argc >= 6 ?
float(atof(argv[5])) : numeric_limits<float>::infinity());
243 validate<float, Eigen::MatrixXf>(argv[1], K, dim, method, maxRadius);
244 validate<float, Eigen::Matrix3Xf>(argv[1], K, dim, method, maxRadius);
245 validate<float, Eigen::Map<const Eigen::Matrix3Xf, Eigen::Aligned> >(argv[1], K, dim, method, maxRadius);
248 validate<float, Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> >(argv[1], K, dim, method, maxRadius);