flann库是比较常用的k近邻搜索库,支持n维数据点的快速搜索,同时许多开源库也都是用这个,比如opencv,还有点云处理的库PCL。因为opencv也可以调用这个库,所以我直接用opencv进行调用。如果不想要引入opencv库,可以网上下载flann,然后调用里面的c++源码。调用flann需要包含头文件:flann.hpp。在此直接贴个调用这个库,进行快速最近邻快速搜索的函数:
//输入n个数据点vec_hogs,搜索点hog的最近邻,返回最近邻的索引 int getNearIndex(vector<vector<float>> vec_hogs,std::vector<float> hog) { //把n个数据点转为flann参数矩阵形式 int n_feature=hog.size();//特征维数 cv::Mat brow_mat(vec_hogs.size(),n_feature,CV_32FC1);//把数据点存为矩阵,其中,M(i,j)表示第i个点的第j维数据 for (int i=0;i<vec_hogs.size();i++) { vector<float>&brow_vec=vec_hogs[i]; for (int j=0;j<brow_vec.size();j++) { brow_mat.at<float>(i,j)=brow_vec[j]; } } //建立kd树 flann::Index knn( brow_mat,cv::flann::KDTreeIndexParams()); //把数据点hog转换成矩阵 ,矩阵大小为1行, n_feature列, //如果你要同时搜索m个数据点的最近邻点,那么矩阵为m行,n_feature列 cv::Mat ser(1,n_feature,CV_32FC1); for (int i=0;i<hog.size();i++) { ser.at<float>(0,i)=hog[i]; } //搜索 int num_knn=1;//这个参数是用于设置搜索最邻近点的个数的,因为我只要搜索一个最近的点,所以设置为1 cv::Mat nearest_index_result; cv::Mat nearest_dist_result; knn.knnSearch(ser,nearest_index_result,nearest_dist_result,num_knn); //获取结果,返回的nearest_index_result、nearest_dist_result矩阵的大小为(ser.rows,num_knn),因为我这里指搜索一个数据点的一个最近邻点,所以返回的 //矩阵大小为(1,1) float nearest_dist=nearest_dist_result.at<float>(0,0); int nearest_index=nearest_index_result.at<int>(0,0); return nearest_index; }
构建kd-tree,并保存。然后通过读取的方式,构建kd树,实现调用方法如下:
//输入n个数据点vec_hogs,搜索点hog的最近邻,返回最近邻的索引 int getNearIndex(vector<vector<float>> vec_hogs,std::vector<float> hog) { //把n个数据点转为flann参数矩阵形式 int n_feature=hog.size();//特征维数 cv::Mat brow_mat(vec_hogs.size(),n_feature,CV_32FC1);//把数据点存为矩阵,其中,M(i,j)表示第i个点的第j维数据 for (int i=0;i<vec_hogs.size();i++) { vector<float>&brow_vec=vec_hogs[i]; for (int j=0;j<brow_vec.size();j++) { brow_mat.at<float>(i,j)=brow_vec[j]; } } //建立kd树 flann::Index knn( brow_mat,cv::flann::KDTreeIndexParams()); //把构建树的索引保存下来 knn.save("kd_treed.fln"); //把数据点hog转换成矩阵 ,矩阵大小为1行, n_feature列, //如果你要同时搜索m个数据点的最近邻点,那么矩阵为m行,n_feature列 cv::Mat ser(1,n_feature,CV_32FC1); for (int i=0;i<hog.size();i++) { ser.at<float>(0,i)=hog[i]; } //搜索 int num_knn=1;//这个参数是用于设置搜索最邻近点的个数的,因为我只要搜索一个最近的点,所以设置为1 cv::Mat nearest_index_result; cv::Mat nearest_dist_result; //直接读取文件 kd_treed.fln,这样可以避免有的时候需要重复搜索最近邻点,而需要重复构建kd树 //第一个参数必须是原有数据,第二个参数调用函数cv::flann::SavedIndexParams()加载索引 cv::flann::Index flann_index(brow_mat,cv::flann::SavedIndexParams("kd_treed.fln")); //搜索最近邻点 flann_index.knnSearch(ser,nearest_index_result,nearest_dist_result,num_knn); //获取结果,返回的nearest_index_result、nearest_dist_result矩阵的大小为(ser.rows,num_knn),因为我这里指搜索一个数据点的一个最近邻点,所以返回的 //矩阵大小为(1,1) float nearest_dist=nearest_dist_result.at<float>(0,0); int nearest_index=nearest_index_result.at<int>(0,0); return nearest_index; }本文地址: http://blog.csdn.net/hjimce/article/details/47297241 作者:hjimce 联系qq:1393852684 更多资源请关注我的博客:http://blog.csdn.net/hjimce 原创文章,版权所有,转载请保留本行信息