FLANN-use

为什么用flann

在点集X中存储了大量点,给定一个点y并需要在X中寻找距离点y最近的一个点或者多个点时,通常采用硬查找或者近似最近邻的方式进行查找。而点数越多、维度越高,硬查找的方法将会消耗大量的时间,但是找到的结果精度是较高的。为了提升效率我们可以通过近似最近邻的方法查找最近点。
关于这方面的库主要由ANN(2010),flann(2013),之前一直使用的是ANN,但是觉得效率方面并不是很理想。因此现在对flann进行调研与使用,flann与ann相比方法更加完备,使用起来可选择的方法更多,并且可以调用OPENMP、CUDA等对搜索进行加速,号称比ANN的速度快一个数量级,但用起来稍微麻烦一点。

怎么用flann

在flann的官网中可以下载其源码,可以绑定到C++、C、MATLAB、python,但是自己是使用C++写的。我主要是结合说明手册以及自己在C++中的使用方法与效率对比进行一个测试和使用记录。

多thread支持

可以选择多内核进行搜索,选择的方式是使用参数SearchParams,默认是单核计算的,可以通过设置这个参数的数值来使用内核数,也可以将参数设置为0,表示使用尽可能多的核来计算。

flann使用

我主要是看的C++使用,关于matlab C python的使用可以通过说明书再细看。

头文件

flann.hpp

3.1.1 flann::Index

FLANN的最近邻搜索类,这个类用于适应于不同类型的最近邻索引。这个点用于计算距离函数。

flann::Index::Index 构造函数

参数features,是包含用于构建索引的特征的矩阵;
参数params,是包含索引参数的结构,这个参数选择了搜索的方式,主要包括一下几种:

  • LinearIndexParams 线性的、暴力(brute-force)的搜索。
  • KDTreeIndexParams kd树构成(randomized kd-trees),它可以平行地进行搜索。
struct KDTreeIndexParams : public IndexParams
{KDTreeIndexParams( int trees = 4 );
};
  • KMeansIndexParams 层次k均值树
struct KMeansIndexParams : public IndexParams
{KMeansIndexParams(int branching = 32,//The branching factor to use for the hierarchical k-means treeint iterations = 11,//If a value of -1,should be iterated
until convergenceflann_centers_init_t centers_init = CENTERS_RANDOM,float cb_index = 0.2 );
};
  • CompositeIndexParams 随机kd树与层次k均值树相结合
  • KDTreeSingleIndexParams 仅仅是一个k-d树为低维度的搜索(如3D点云数据)
  • KDTreeCuda3dIndexParams 运用CUDA的k-d树搜索,这最好用在有大量搜索和查询点的时候
  • HierarchicalClusteringIndexParams hierarchical clustering index
  • LshIndexParams 该结构使用multi-probe LSH方法创建索引
  • AutotunedIndexParams 自动选择最好的以上结构
  • SavedIndexParams 从文件中读取索引
centers init

这个参数用来选择在搜索时,选择初始中心的方法。可能之有:
CENTERS RANDOM:随即产生
CENTERS GONZALES:使用Gonzales’的算法
CENTERS KMEANSPP:D. Arthur and S. Vassilvitskii. k-means++中提到的方法。

3.1.2 flann::Index::buildIndex

创建最近邻索引可以使用两种方式:一个是传入点进去,一种是使用构造函数时传入的点。也就是这个借口可以选择不传参数。

void buildIndex();
void buildIndex(const Matrix<ElementType>& points);

3.1.3 flann::Index::addPoints/removePoint

在索引已经建立之后也可以增加和减少点。为了避免索引失衡,addPoints提供了在新增大量数据后的重建索引,参数rebuild threshold=2表示点云增加为size的两倍。removePoint一般不改变索引结构

3.1.5 flann::Index::getPoint

ElementType* getPoint(size_t point_id);不知道这里的point_id指的是什么?

3.1.6 flann::Index::knnSearch

是一个K邻域搜索,可以选择输出类型为matrix或者vector。用vector的话就不需要先限定数组的大小,能够自己扩展。

int Index::knnSearch(const Matrix<ElementType>& queries,//查询点。点数×维度Matrix<int>& indices,//返回的最近点数据 num queries × knnMatrix<DistanceType>& dists, //返回最近点的距离 num_queries×knnsize_t knn,//最近邻的个数const SearchParams& params);//搜索参数int Index::knnSearch(const Matrix<ElementType>& queries,std::vector< std::vector<int> >& indices,std::vector<std::vector<DistanceType> >& dists,size_t knn,const SearchParams& params);struct SearchParams
{SearchParams(int checks = 32,float eps = 0,bool sorted = true);int checks;//检测点 CHECKS UNLIMITED CHECKS AUTOTUNEDfloat eps;//KD treebool sorted;//Used only by radius search, specifies if the neighbors returned should be sorted by distance.int max_neighbors;//Used only by radius search, 最多返回的点数tri_type use_heap;//int cores; //内核数 0表示自动选择bool matrices_in_gpu_ram;//
};

3.1.7 flann::Index::radiusSearch

与knn基本相同,只是最近的点数变为了半径大小

3.1.8 flann::Index::save

把索引表存入文件中,
void Index::save(std::string filename);

3.1.9 flann::hierarchicalClustering

使用多层次k均值树

3.1.10 flann::KdTreeCuda3dIndex

提供了CUDA为提升建立和查询速度的三维点云数据。首先需要在安装时候选择上CUDA选项才可以。

时间测试:

LinearIndexParams(): 0.460
KDTreeIndexParams(4): 0.58
KMeansIndexParams(): 0.290
CompositeIndexParams(): 0.280
KDTreeSingleIndexParams(): 0.20
LshIndexParams():error
HierarchicalClusteringIndexParams(): 0.500
AutotunedIndexParams(): 0.850??
搜索时候的配置都是全核: 二维坐标点 点数共有360个,搜索大概1200*180次

flann::SearchParams mypapra(16,0.1,false);mypapra.cores = 0;
//        mypapra.checks=flann::CHECKS AUTOTUNED;index_->knnSearch(*query_, *indics_, *dists_, 1, mypapra);

EX:

        flann::Matrix<float> *dataset_;flann::Matrix<float> *query_;flann::Matrix<int> *indics_;flann::Matrix<float> *dists_;flann::Index<flann::L2<float> > *index_;void cleanFLANN();
  dataset_ = new flann::Matrix<float>(new float[maxPts*dim], maxPts, dim);for(int i=0; i<nsites; ++i){(*dataset_)[i][0]=points[i].x();(*dataset_)[i][1]=points[i].y();}
query_ = new flann::Matrix<float>(new float[k*dim], k, dim);dists_ = new flann::Matrix<float>(new float[k*dim], k, dim);indics_ = new flann::Matrix<int>(new int[k*dim], k, dim);index_ = new flann::Index<flann::L2<float> >(*dataset_,flann::KDTreeSingleIndexParams());index_->buildIndex();void VoronoiDiagramGenerator::cleanFLANN()
{if(dataset_){delete[] dataset_->ptr();delete[] dataset_;dataset_ = NULL;}//TODO:QY 下面这三个可以不清除内存的,反正每次都是寻找一个最近点。if(query_){delete[] query_->ptr();delete[] query_;query_ = NULL;}if(indics_){delete[] indics_->ptr();delete[] indics_;indics_ = NULL;}if(dists_){delete[] dists_->ptr();delete[] dists_;dists_ = NULL;}
}//search*query_[0][0] = x;*query_[0][1] = x;flann::SearchParams mypapra(16,0.1,false);mypapra.cores = 0;index_->knnSearch(*query_, *indics_, *dists_, 1, mypapra);return sqrt(*dists_[0][0]);

insall FLANN with CUDA

FLANN支持GPU并行计算,但是在安装时就需要选择并行。
1.刚开始在flann的发行版上进行安装未成功,因为后期CUDA版本更新,作者对flann进行了修改,但是没有把修改后的发行。因此1.8.4的发行版对cuda8.0不支持。因此我在github上下载了最新的flann-master原文件进行安装。
一直出现如下错误:

2.在cmake后打开CMakeCache.txt,选择CUDA-LIB,并把我不需要的Matlab的勾取消。

3.make
4.sudo make install

ALGLIB use

直接在官网下载源码,将源码放在项目中并进行了测试。
搜索条件:二维坐标点 点数共有360个,搜索大概1200*180次
时间为0.160s,与flann的最快搜索时间基本相同。

ANN-USE

搜索条件:二维坐标点 点数共有360个,搜索大概1200*180次
ANN_KD_STD = 0, // the optimized kd-splitting rule ERROR
ANN_KD_MIDPT = 1, // midpoint split 搜索时间为0.07s
ANN_KD_FAIR = 2, // fair split 搜索时间为0.08s
ANN_KD_SL_MIDPT = 3, // sliding midpoint splitting method 搜索时间为0.08s
ANN_KD_SL_FAIR = 4, // sliding fair split method //搜索时间为0.06s
ANN_KD_SUGGEST= 5}; // the authors’ suggestion for best 搜索时间为0.06ms
ANN_KD_SUGGEST对应下的搜索方式的时间开销:

  • annkPriSearch:0.15s
  • annkSearch: 0.06s
  • annkFRSearch: 按照半径2.5m进行搜索,时间为0.055s !! 这种求最短距离的早该想到在固定半径内查找最近点!!

ann flann alglibB最近邻方法时效性探索相关推荐

  1. 《PCL点云库学习VS2010(X64)》Part 37 FLANN——快速最近邻搜索库

    <PCL点云库学习&VS2010(X64)>Part 37 FLANN--快速最近邻搜索库 一.介绍 该算法库在OpenCV和PCL等开源库中应用较广,是PCL的默认安装库之一.与 ...

  2. 最近邻方法和向量模型——第一部分

    作者:Erik Bernhardsson 这篇博客是在我上周NYC MachineLearning做得报告基础上改写而成的.内容中包括Annoy,我开源的一个高维空间求(近似)最近邻的工具库.在接下来 ...

  3. NSIS:延时启动软件的几个方法及探索

    原文 NSIS:延时启动软件的几个方法及探索 有时候,我们想要某软件开机启动,但又不要拖慢开机速度,那么,延时启动技术就显得比较重要了.轻狂在这方面曾经研究过,也实现了自己想要的功能,看看我是怎么做的 ...

  4. 【图像处理】——特征匹配(SIFT特征检测器+FLANN特征匹配方法+KNN近邻最优匹配筛选)——cv.xfeatures2d.SIFT_create()sift.detectAndCompute

    转载请注明地址 目录 1.特征检测和特征匹配方法 (1)特征检测算法 (2)特征匹配算法 (3)各种特征检测算法的比较 2.特征匹配的基本步骤(附带主要的函数) (1)图像预处理--灰度化(模板--查 ...

  5. 学习OpenCV——Surf(特征点篇)flann快速最近邻搜索算法

    Surf(Speed Up Robust Feature) Surf算法的原理                                                             ...

  6. 数据中心电池室管理之经济实用性方法的探索

          "2014年7月21日重庆某商业银行数据中心电池短路引发火灾: 2017年4月4日北京某大学UPS蓄电池组发生火灾: 2017年11月21日澳大利亚凯尔斯市卫生中心数据机房电池室 ...

  7. 计算机课平时成绩重要吗,离散数学课程平时成绩评定方法的探索与研究

    林静 史册 摘要:离散数学是计算机科学与技术专业重要的核心基础课程.目前,不少大学离散数学课程的最终成绩是依据平时成绩和期终考试成绩两个部分综合评定的.为了提高课程评价的公正性和提升教学效果,文章對该 ...

  8. 独家 | 神经网络的对抗性攻击:快速梯度符号方法的探索(附链接)

    作者:Patrycja Jenkner 翻译:陈之炎 校对:欧阳锦 本文约2300字,建议阅读8分钟 本文将尝试一种非常流行的攻击:快速梯度符号方法,来证明神经网络的安全漏洞. 标签:对抗性攻击,神经 ...

  9. 颜色的识别方法和探索 基于matlab

    颜色的rgb的图像方法 clc clear close all load 2.mat  figure subplot(221) imshow(d); picture_1 =d;% imread(str ...

最新文章

  1. 自定义注解做数据验证
  2. 用WebBrowser实现HTML界面的应用和交互
  3. 【JavaService】部署Java jar为Windows后台服务
  4. kali linux set工具,求助: 社会工程学工具set 出现错误for kali linux.
  5. 行星齿轮设计_行星减速机内部结构图与传动原理
  6. UDP --02--UDP广播数据
  7. javac与java版本不一致
  8. 最先进的语义搜索句子相似度计算
  9. 点钞机语音怎么打开_我有这些语音识别指令,你都知道吗?
  10. matlab所有元素求和,数组 – MATLAB对数组值表达式的所有元素求和
  11. 重装电脑系统完整教程
  12. C#操作三菱FX系列PLC数据
  13. 数量关系-排列组合和概率
  14. abp 链接本地mysql_ABP Vnext使用mysql数据库
  15. 智慧企业的基础——知识中台
  16. 32位驱动模式写保护开关
  17. 网易云音乐数据治理探索与实践
  18. 去掉office2003盗版五角星的办法
  19. python 分词库jieba
  20. 【PHP】高德地图经纬度和地址转换

热门文章

  1. 【无线网络技术】WLAN技术学习笔记
  2. 最详细的Android图片压缩解释
  3. 5G应用创新发展策略研究
  4. XBee zigbee 使用指南--- XBee模块输入和输出
  5. 硬件工程师基本功:AD的DRC设置要点详解
  6. python办公自动化之word表格跨页断行-AllowBreakAcrossPages
  7. word中表格剩最后一行,一旦超过两行自动跳到下一页
  8. A problem has occurred and the system can‘t recover问题的解决
  9. 十个英语口语学习网站
  10. [ENVI]练习过程中遇到的一些问题