我使用的是opencv 2.4.4 flann。
和我参考:http://docs.opencv.org/2.4.4/modules/flann/doc/flann_fast_approximate_nearest_neighbor_search.html
做KNN.
我有一个矩阵(8000*32)flann_m。有8000个数据,每个数据有32个特征。我写了这样的代码:
flann::Index flann_index(flann_m, flann::LinearIndexParams());
flann_index.save("flann_index.fln");
Mat resps(ROW,K,CV_32F);
Mat nresps(ROW,K,CV_16S);
Mat dist(ROW,K,CV_32F);
flann_index.knnSearch(flann_m,nresps,dist,K,flann::SearchParams(64));
我可以得到nresps和dist的KNN结果,其中nresps是N个邻居的索引,dist是距离。
但是我不知道如何在opencv flann中设置不同的距离算法(ChiSquare, Euclidean等)
我检查了flann_cpp,似乎set_distance()函数已经过时了。
我注意到很少有人熟悉openCV,而且很少有文档。最后,我通过使用openvflann而不是flann来避免名称空间冲突。在检查了openv源代码后,我发现"dist.h"是一个有用的文件,可以找到如何设置不同的KNN距离类型。
在我的代码中,我使用曼哈顿距离,参考openv源代码中的dist.h。
//// do indexing
Matrix<float> samplesMatrix((float*)flann_m.data, flann_m.rows, flann_m.cols);
//Index<cvflann::ChiSquareDistance<float>> flann_index(samplesMatrix, cvflann::LinearIndexParams());
Index<cvflann::L1<float>> flann_index(samplesMatrix, cvflann::LinearIndexParams());
flann_index.buildIndex();
cv::Mat1i ind(flann_m.rows, K);
CV_Assert(ind.isContinuous());
cvflann::Matrix<int> nresps((int*) ind.data, ind.rows, ind.cols);
cvflann::Matrix<float> dist(new float[flann_m.rows*K], flann_m.rows, K);
flann_index.knnSearch(samplesMatrix,nresps,dist,K,SearchParams(64));