热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PCL中使用FLANN库(1)

FLANN库全称是FastLibraryforApproximateNearestNeighbors,它是目前最完整的(近似)最近邻开源库。不但实现了一系列查找算法,还包含了一种自

FLANN库全称是Fast Library for Approximate Nearest Neighbors,它是目前最完整的(近似)最近邻开源库。不但实现了一系列查找算法,还包含了一种自动选取最快算法的机制,在一个度量空间X给定一组点P=p1,p2,…,pn,这些点必须通过以下方式进行预处理,给第一个新的查询点q属于X,快速在P中找到距离q最近的点,即最近邻搜索问题。最近邻搜索的问题是在很多应用领域是一个重大问题,如图像识别、数据压缩、模式识别和分类.在高维空间中解决这个问题似乎是一个非常难以执行任务,没有算法明显优于标准的蛮力搜索。因此越来越多的人把兴趣点转向执行近似最近邻搜索的一类算法,这些方法在很多实际应用和大多数案例中被证明是足够好的近似,比精确搜索算法快很大的数量级

库的地址:www.cs.ubc.ca/research/flann/

很显然在PCL 搜索最近邻也是属于高维度近邻搜索,所以需要用到这样的库来寻找匹配的,比如我们如果想通过使用PCL点云的数据来识别出物体到底是什么,那么很明显是需要一个数据录的,这个数据库的训练该怎么来实现呢?因为我对机器学习了解的比较少,我想通过机器学习的方法来识别是最好的,也是今后可以做的工作,目前来看,我认为的方法就是通过对大量的点云进行训练并提取他们的特征点,比如VFH,然后把大量点云训练存储成八叉树,以便于很好的搜索和匹配,而且在PCL 中使用八叉树是很常见的一种存储结构,也是方便搜索的,然后通过计算我们想要识别物体的点云 的VFH,通过FLANN算法寻找到最接近的,这就是整体的思路

主要流程

  1. 使用SURF,SIFT特征提取关键点(在PCL中同样适用)
  2. 计算特征描述子(比如VFH)
  3. 使用FLANN匹配器进行描述子向量匹配

那么有兴趣可以去仔细看看论文啊,我等渣渣真是多年以来对论文没什么感觉

介绍几种FLANN库中的API接口,如何去使用它,然后通过具体的实例去实现这样一个匹配

(1)flann::Index这是FLANN最近邻指数类。该类用于抽象的不同类型的最近邻搜索索引。距离函数类模板用于计算两个特征空间之间的距离。

namespace flann
 {
     template
     class Index
     {
         typedef typename Distance::ElementType ElementType;
         typedef typename Distance::ResultType DistanceType;
     public:
         Index(const IndexParams& params, Distance distance = Distance() );
         Index(const Matrix& points, const IndexParams& params,
                 Distance distance = Distance() );
         ~Index();
         void buildIndex();
         void buildIndex(const Matrix& points);
         void addPoints(const Matrix& points,
                        float rebuild_threshold = 2);
         void removePoint(size_t point_id);
         ElementType* getPoint(size_t point_id);
         int knnSearch(const Matrix& queries,
                        Matrix<int>& indices,
                        Matrix& dists,
                        size_t knn,
                        const SearchParams& params);
         int knnSearch(const Matrix& queries,
                        std::vectorint> >& indices,
                        std::vector >& dists,
                        size_t knn,
                        const SearchParams& params);
         int radiusSearch(const Matrix& queries,
                          Matrix<int>& indices,
                          Matrix& dists,
                          float radius,
                          const SearchParams& params);
         int radiusSearch(const Matrix& queries,
                           std::vectorint> >& indices,
                           std::vector >& dists,
                           float radius,
                           const SearchParams& params);
         void save(std::string filename);
         int veclen() const;
         int size() const;
         IndexParams getParameters() const;
         flann_algorithm_t getType() const;
}; }

(2)flann::Index::knnSearch

对一组点查询点,该方法执行K最近邻搜索。该方法有两个实现,一个携带预开辟空间的flann::Matrix对象接收返回的找到邻居的索引号和到其距离;另一个是携带std::vector根据需要自动重新调整大小。

参数解释:

queries: 承载查询点的矩阵,矩阵大小是:查询点数*纬数;

indices: 将承载所有被找到的K最近邻的索引号( 预开辟的大小应该至少是查询点数*knn);

dists:     将承载到所有被找到的K最近邻的距离只(预开辟大小应该至少是查询点数*knn);

knn:       要找的最近邻的个数;

params: 搜索参数。承载搜索时要使用的参数的结构体,结构体类型是SearchParameters。

int Index::knnSearch(const Matrix& queries,
                Matrix<int>& indices,
                Matrix& dists,
                size_t knn,
                const SearchParams& params);
int Index::knnSearch(const Matrix& queries,
                std::vectorint> >& indices,
                std::vector >& dists,
                size_t knn,
                const SearchParams& params); 

 在这里就不再一一翻译了

/**
   Sets the log level used for all flann functions (unless
   specified in FLANNParameters for each call

   Params:
    level = verbosity level
 */
FLANN_EXPORT void flann_log_verbosity(int level);

设置FLANN距离的类型

/**
 * Sets the distance type to use throughout FLANN.
 * If distance type specified is MINKOWSKI, the second argument
 * specifies which order the minkowski distance should have.
 */
FLANN_EXPORT void flann_set_distance_type(enum flann_distance_t distance_type, int order);

建立和返回索引的函数

/**
   Builds and returns an index. It uses autotuning if the target_precision field of index_params
   is between 0 and 1, or the parameters specified if it‘s -1.

   Params:
    dataset = pointer to a data set stored in row major order
    rows = number of rows (features) in the dataset
    cols = number of columns in the dataset (feature dimensionality)
    speedup = speedup over linear search, estimated if using autotuning, output parameter
    index_params = index related parameters
    flann_params = generic flann parameters

   Returns: the newly created index or a number <0 for error
 */
FLANN_EXPORT flann_index_t flann_build_index(float* dataset,
                                             int rows,
                                             int cols,
                                             float* speedup,
                                             struct FLANNParameters* flann_params);

保存索引到本地磁盘(仅仅是索引被保存)

/**
 * Saves the index to a file. Only the index is saved into the file, the dataset corresponding to the index is not saved.
 *
 * @param index_id The index that should be saved
 * @param filename The filename the index should be saved to  文件名
 * @return Returns 0 on success, negative value on error.  返回0则保存成功
 */
FLANN_EXPORT int flann_save_index(flann_index_t index_id,
                                  char* filename);

从磁盘中载入索引文件

/**
 * Loads an index from a file.
 *
 * @param filename File to load the index from.
 * @param dataset The dataset corresponding to the index.
 * @param rows Dataset tors
 * @param cols Dataset columns
 * @return
 */
FLANN_EXPORT flann_index_t flann_load_index(char* filename,
                                            float* dataset,
                                            int rows,
                                            int cols);

建立一个索引或者说指定一个索引来寻找最近邻域

/**
   Builds an index and uses it to find nearest neighbors.

   Params:
    dataset = pointer to a data set stored in row major order
    rows = number of rows (features) in the dataset
    cols = number of columns in the dataset (feature dimensionality)
    testset = pointer to a query set stored in row major order
    trows = number of rows (features) in the query dataset (same dimensionality as features in the dataset)
    indices = pointer to matrix for the indices of the nearest neighbors of the testset features in the dataset
            (must have trows number of rows and nn number of columns)
    nn = how many nearest neighbors to return
    flann_params = generic flann parameters

   Returns: zero or -1 for error
 */
FLANN_EXPORT int flann_find_nearest_neighbors(float* dataset,
                                              int rows,
                                              int cols,
                                              float* testset,
                                              int trows,
                                              int* indices,
                                              float* dists,
                                              int nn,
                                              struct FLANNParameters* flann_params);

对提供的索引来寻找最近邻

/**
   Searches for nearest neighbors using the index provided

   Params:
    index_id = the index (constructed previously using flann_build_index).
    testset = pointer to a query set stored in row major order
    trows = number of rows (features) in the query dataset (same dimensionality as features in the dataset)
    indices = pointer to matrix for the indices of the nearest neighbors of the testset features in the dataset
            (must have trows number of rows and nn number of columns)
    dists = pointer to matrix for the distances of the nearest neighbors of the testset features in the dataset
            (must have trows number of rows and 1 column)
    nn = how many nearest neighbors to return
    flann_params = generic flann parameters

   Returns: zero or a number <0 for error
 */
FLANN_EXPORT int flann_find_nearest_neighbors_index(flann_index_t index_id,
                                                    float* testset,
                                                    int trows,
                                                    int* indices,
                                                    float* dists,
                                                    int nn,
                                                    struct FLANNParameters* flann_params);

半径搜索的方法在已经建立的索引文件中寻找

/**
 * Performs an radius search using an already constructed index.
 *
 * In case of radius search, instead of always returning a predetermined
 * number of nearest neighbours (for example the 10 nearest neighbours), the
 * search will return all the neighbours found within a search radius
 * of the query point.
 *
 * The check parameter in the FLANNParameters below sets the level of approximation
 * for the search by only visiting "checks" number of features in the index
 * (the same way as for the KNN search). A lower value for checks will give
 * a higher search speedup at the cost of potentially not returning all the
 * neighbours in the specified radius.
 */
FLANN_EXPORT int flann_radius_search(flann_index_t index_ptr, /* the index */
                                     float* query, /* query point */
                                     int* indices, /* array for storing the indices found (will be modified) */
                                     float* dists, /* similar, but for storing distances */
                                     int max_nn,  /* size of arrays indices and dists */
                                     float radius, /* search radius (squared radius for euclidian metric) */
                                     struct FLANNParameters* flann_params);

释放内存

/**
   Deletes an index and releases the memory used by it.

   Params:
    index_id = the index (constructed previously using flann_build_index).
    flann_params = generic flann parameters

   Returns: zero or a number <0 for error
 */
FLANN_EXPORT int flann_free_index(flann_index_t index_id,
                                  struct FLANNParameters* flann_params);

利用特征聚类

/**
   Clusters the features in the dataset using a hierarchical kmeans clustering approach.
   This is significantly faster than using a flat kmeans clustering for a large number
   of clusters.

   Params:
    dataset = pointer to a data set stored in row major order
    rows = number of rows (features) in the dataset
    cols = number of columns in the dataset (feature dimensionality)
    clusters = number of cluster to compute
    result = memory buffer where the output cluster centers are storred
    index_params = used to specify the kmeans tree parameters (branching factor, max number of iterations to use)
    flann_params = generic flann parameters

   Returns: number of clusters computed or a number <0 for error. This number can be different than the number of clusters requested, due to the
    way hierarchical clusters are computed. The number of clusters returned will be the highest number of the form
    (branch_size-1)*K+1 smaller than the number of clusters requested.
 */

FLANN_EXPORT int flann_compute_cluster_centers(float* dataset,
                                               int rows,
                                               int cols,
                                               int clusters,
                                               float* result,
                                               struct FLANNParameters* flann_params);

基本的介绍,可以查看相应的手册

#include
#include

其中还涉及到另外一种文件的数据结构的使用,一般都会包含两个头文件,第一个头文件是关于FLANN算法实现的声明的函数集,第二个头文件是关于数据结构的一种存储的方式,hdf5是用于存储和分发科学数据的一种自我描述、多对象文件格式,HDF 被设计为:

  • 自述性:对于一个HDF 文件里的每一个数据对象,有关于该数据的综合信息(元数据)。在没有任何外部信息的情况下,HDF 允许应用程序解释HDF文件的结构和内容。
  • 通用性:许多数据类型都可以被嵌入在一个HDF文件里。例如,通过使用合适的HDF 数据结构,符号、数字和图形数据可以同时存储在一个HDF 文件里。
  • 灵活性:HDF允许用户把相关的数据对象组合在一起,放到一个分层结构中,向数据对象添加描述和标签。它还允许用户把科学数据放到多个HDF 文件里。
  • 扩展性:HDF极易容纳将来新增加的数据模式,容易与其他标准格式兼容。
  • 跨平台性:HDF 是一个与平台无关的文件格式。HDF 文件无需任何转换就可以在不同平台上使用

最好的办法是把HDF 文件看成为一本有表格内容的多章节书。HDF 文件是“数据书”,其中每章都包含一个不同类型的数据内容。正如书籍用一个目录表列出它的章节一样,HDF文件用“data index”(数据索引)列出其数据内容技术分享图片

HDF 文件结构包括一个file id(文件号)、至少一个 data descriptor (数据描述符)、没有或多个 data element(数据内容)数据内容。

以上内容是涉及到关于对PCL中物体的识别的基础知识。

有兴趣者关注微信公众号,更欢迎大家投稿分享,只要是关于点云的都可以分享

技术分享图片

PCL中使用FLANN库(1)


推荐阅读
  • 二分查找算法详解与应用分析:本文深入探讨了二分查找算法的实现细节及其在实际问题中的应用。通过定义 `binary_search` 函数,详细介绍了算法的逻辑流程,包括初始化上下界、循环条件以及中间值的计算方法。此外,还讨论了该算法的时间复杂度和空间复杂度,并提供了多个应用场景示例,帮助读者更好地理解和掌握这一高效查找技术。 ... [详细]
  • 在 Android 开发中,`android:exported` 属性用于控制组件(如 Activity、Service、BroadcastReceiver 和 ContentProvider)是否可以被其他应用组件访问或与其交互。若将此属性设为 `true`,则允许外部应用调用或与之交互;反之,若设为 `false`,则仅限于同一应用内的组件进行访问。这一属性对于确保应用的安全性和隐私保护至关重要。 ... [详细]
  • 深入解析Java虚拟机的内存分区与管理机制
    Java虚拟机的内存分区与管理机制复杂且精细。其中,某些内存区域在虚拟机启动时即创建并持续存在,而另一些则随用户线程的生命周期动态创建和销毁。例如,每个线程都拥有一个独立的程序计数器,确保线程切换后能够准确恢复到之前的执行位置。这种设计不仅提高了多线程环境下的执行效率,还增强了系统的稳定性和可靠性。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • POJ 2482 星空中的星星:利用线段树与扫描线算法解决
    在《POJ 2482 星空中的星星》问题中,通过运用线段树和扫描线算法,可以高效地解决星星在窗口内的计数问题。该方法不仅能够快速处理大规模数据,还能确保时间复杂度的最优性,适用于各种复杂的星空模拟场景。 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 这是一道涉及数学计算的问题。假设步行速度为 \(a\),车速为 \(b\),总距离为 \(c\)。Teddy 的步行时间为 \(T_1\),WhereIsHeroFrom 的步行时间为 \(T_2\),总时间为 \(T\)。通过分析不同时间段内的速度变化,可以得出最优的车辆使用策略,以最小化总的旅行时间。具体来说,需要计算在不同情况下步行和乘车的时间分配,以确保整体效率最大化。 ... [详细]
  • 在 Mac 上查看隐藏文件和文件夹的详细指南。通过终端命令,您可以轻松地显示或隐藏这些文件。具体步骤如下:输入 `defaults write com.apple.finder AppleShowAllFiles -bool true` 以显示所有隐藏文件,或使用 `defaults write com.apple.finder AppleShowAllFiles -bool false` 以重新隐藏它们。此方法适用于各种版本的 macOS,帮助用户更好地管理和访问系统文件。 ... [详细]
  • 深入解析Linux内核中的进程上下文切换机制
    在现代操作系统中,进程作为核心概念之一,负责管理和分配系统资源,如CPU和内存。深入了解Linux内核中的进程上下文切换机制,需要首先明确进程与程序的区别。进程是一个动态的执行流,而程序则是静态的数据和指令集合。进程上下文切换涉及保存当前进程的状态信息,并加载下一个进程的状态,以实现多任务处理。这一过程不仅影响系统的性能,还关系到资源的有效利用。通过分析Linux内核中的具体实现,可以更好地理解其背后的原理和技术细节。 ... [详细]
  • 如何在PDF文档中添加新的文本内容?
    在处理PDF文件时,有时需要向其中添加新的文本内容。这是否可以直接实现呢?有哪些简便且免费的方法可供选择?使用极速PDF阅读器打开文档后,可以通过点击左上角的“注释”按钮切换到注释模式,并选择相应的工具进行编辑。此外,还可以利用其他功能丰富的PDF编辑软件,如Adobe Acrobat DC或Foxit PhantomPDF,它们提供了更多高级的编辑选项,能够满足更复杂的需求。 ... [详细]
  • 在 Axublog 1.1.0 版本的 `c_login.php` 文件中发现了一个严重的 SQL 注入漏洞。该漏洞允许攻击者通过操纵登录请求中的参数,注入恶意 SQL 代码,从而可能获取敏感信息或对数据库进行未授权操作。建议用户尽快更新到最新版本并采取相应的安全措施以防止潜在的风险。 ... [详细]
  • Nginx 反向代理配置与应用指南
    本文详细介绍了 Nginx 反向代理的配置与应用方法。首先,用户可以从官方下载页面(http://nginx.org/en/download.html)获取最新稳定版 Nginx,推荐使用 1.14.2 版本。下载并解压后,通过双击 `nginx.exe` 文件启动 Nginx 服务。文章进一步探讨了反向代理的基本原理及其在实际应用场景中的配置技巧,包括负载均衡、缓存管理和安全设置等,为用户提供了一套全面的实践指南。 ... [详细]
  • 本指南详细介绍了如何在CentOS 6.6 64位系统上以root用户身份部署Tomcat 8服务器。系统环境为CentOS 6.6 64位,采用源码安装方式。所需软件为apache-tomcat-8.0.23.tar.gz,建议将软件下载至/root/opt目录。具体下载地址请参见官方资源。本指南涵盖了从环境准备到服务启动的完整步骤,适用于需要在该系统环境下搭建高性能Web应用服务器的技术人员。 ... [详细]
  • 该问题可能由守护进程配置不当引起,例如未识别的JVM选项或内存分配不足。建议检查并调整JVM参数,确保为对象堆预留足够的内存空间(至少1572864KB)。此外,还可以优化应用程序的内存使用,减少不必要的内存消耗。 ... [详细]
  • 在数字图像处理中,Photoshop 的直方图是一个重要的工具,它能够精确地反映图像中不同亮度级别的分布情况。通过分析直方图,用户可以深入了解图像的曝光、对比度和色调范围,从而进行更精细的调整。直方图不仅模拟了物体表面反射光线的原理,还能帮助摄影师和设计师更好地掌握图像的明暗细节,优化视觉效果。 ... [详细]
author-avatar
手机用户2502896257
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有