# how to use opencv2.4.4 flann

Hi,

I'm using opencv 2.4.4 flann.

to do KNN.

I have a matrix(8000*32) flann_m. There are 8000 data and each with 32 features.

I wrote code like this:

    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));


And I could get the KNN results in nresps and dist, with nresps the indexes of N neighbors, and dist the distances.

But I don't know how to set different distance algorithm (ChiSquare, Euclidean, etc.) in opencv flann. I checked flann.cpp, and it seems the set_distance() function is deperecated.

edit retag close merge delete

Sort by » oldest newest most voted

Actually something like

cv::flann::GenericIndex<cv::L1<float> > index()


should work or worked some while ago. However, I get a compiler error here. So afaik - maybe I am wrong here! - this works only with the cvflann-namespace:

cvflann::Index<cvflann::ChiSquareDistance<float> > flann_index(flann_m, cvflann::LinearIndexParams());


However, then you also need to convert your flann_m and your other matrices to flann-matrices, e.g.

cvflann::Matrix<float> samplesMatrix((float*)flann_m.data, flann_m.rows, flann_m.cols);


But in the case you need to use the cvflann-namespace I would immediatly chose to use the original up-to-date flann-library (http://www.cs.ubc.ca/~mariusm/index.php/FLANN/FLANN), their you need to do the same steps but have the advantage of a bug-fixed version (be aware that you don't mix the flann:: and the cv::flann:: namespaces) - this is what I actually use. Let me know if you get it working with the cv::flann::-namespace. Good luck!

UPDATE: Adding working example: (both namespaces cvflann:: and flann:: (using the original library) produced same results

int test_rank = 10;
cvflann::Matrix<float> data( (float*)all_data.data, all_data.rows, all_data.cols );
cvflann::Index<cvflann::ChiSquareDistance<float> > index(data, cvflann::LinearIndexParams());
index.buildIndex();

// make cv::Mat-header for easier access
// (you can do the same with the dists-matrix if you need it)
cv::Mat1i ind(data.rows, test_rank);
CV_Assert(ind.isContinuous());
cvflann::Matrix<int> indices((int*) ind.data, ind.rows, ind.cols);
cvflann::Matrix<float> dists(new float[data.rows*test_rank], data.rows, test_rank);
index.knnSearch(data, indices, dists, test_rank, cvflann::SearchParams(all_data.cols-1));

more

Thanks a lot. I will give it a try.

( 2013-04-08 10:20:49 -0500 )edit

Hi, I tried the original FLANN, and to solve namespace conflict is painful. But I don't know how to link the compiled package to my Visual Studio C++ project, and how to use this FLANN. Could you give me a sample?

By the way, I also tried cvflann namespace, but knnSearch didn't work (abort() has been called)

Matrix<float> samplesMatrix((float*)flann_m.data, flann_m.rows, flann_m.cols); Index<cvflann::ChiSquareDistance<float>> flann_index(samplesMatrix, cvflann::LinearIndexParams()); Matrix<int> nresps; Matrix<float>dist; flann_index.knnSearch(samplesMatrix,nresps,dist,K,SearchParams(64));

( 2013-04-12 01:16:47 -0500 )edit

I am not using Visual Studio C++, but it shouldn't be too difficult. FLANN provides also a cmake file if you are using cmake.

Back to topic: You need to initialize the matrices nresps and dist. I just tried both versions of your code, once using cvflann:: and once using the original flann:: and both worked fine, even gave me both times the same results, so you can also use cvflann:: instead of flann:: . One note: too large training matrices which don't fit in your memory will of course result in an abort(). I will update my post with a small example. Since the problem is solved, please mark the question as correct.

( 2013-04-13 11:28:57 -0500 )edit

Another note (just looked it up): with LinearIndex the SearchParams are ignored.

( 2013-04-13 16:23:27 -0500 )edit

Official site

GitHub

Wiki

Documentation