flann源码安装及示例(最近邻查找和领域查找)

1、介绍

FLANN(近似近邻快速库)是一个用于执行快速近似近邻搜索的库。FLANN是用C++编写的,该库提供的C、MATLAB和Python接口。
源码:https://github.com/flann-lib/flann
文档:https://www.fit.vutbr.cz/~ibarina/pub/VGE/reading/flann_manual-1.6.pdf

2、下载

根据需要,下载相应版本,我下载的是1.9.1
下载链接:Release

3、编译

3.1 Windows

  • 解压下载的压缩包

  • 新建build 利用CMake.exe进行编译

  • 根据需要 选择BUILD选项 和 CMAKE 选项

    • BUILD_MATLAB_BINDINGS OFF
    • BUILD_PYTHON_BINDINGS OFF
    • BUILD_EXAMPLES OFF
    • BUILD_DOC ON
    • CMAKE_INSTALL_PREFIX (默认在C盘)
  • Visual Studio 打开 flann.sln

    • 选择Debug或者Release

    • 右键ALL_BUILD >>> 生成

    • 右键INSTALL >>> 仅用于项目 >>> 仅生成INSTALL

3.2 Linux

  • 解压文件

  • 新建build

  • 进入build目录,设置编译选项

    cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PYTHON_BINDINGS=OFF -DBUILD_MATLAB_BINDINGS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTS=OFF -DBUILD_DOC=OFF -DCMAKE_INSTALL_PREFIX="./install_res" ..
    
  • 利用make进行编译

    make -j4
    
  • 安装

    make install
    

4、示例

最近邻查找和领域查找

CMakeLists.txt
cmake_minimum_required(VERSION 3.9)

project(TestFlann)

# set verbose makefile
set(CMAKE_VERBOSE_MAKEFILE ON)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# Flann
if(WIN32)
   set(FLANN_DIR "E:/ThirdPartySoftware/Flann/install_res/flann_mini")
  set(FLANN_INCLUDE_PATH "${FLANN_DIR}/include" CACHE INTERNAL "")
  set(FLANN_LIBRARIES 
      # "${FLANN_DIR}/lib/Win/Release/flann.lib"
      "${FLANN_DIR}/lib/Win/Release/flann_cpp_s.lib"
      # "${FLANN_DIR}/lib/Win/Release/flann_s.lib"
      CACHE INTERNAL "")
  set(FLANN_LIBRARIES_DEBUG
      # "${FLANN_DIR}/lib/Win/Debug/flann.lib"
      "${FLANN_DIR}/lib/Win/Debug/flann_cpp_s.lib"
      # "${FLANN_DIR}/lib/Win/Debug/flann_s.lib"
      CACHE INTERNAL "")

  # file(GLOB TMP_SO_FILES "${FLANN_DIR}/bin/Win/Release/*.dll")
  # file(GLOB TMP_SO_FILES_DEBUG "${FLANN_DIR}/bin/Win/Debug/*.dll")
  set(TMP_SO_FILES "${FLANN_DIR}/bin/Win/Release/flann_cpp.dll")
  set(TMP_SO_FILES_DEBUG "${FLANN_DIR}/bin/Win/Debug/flann_cpp.dll")
  set(FLANN_RUNTIME_LIBRARIES ${TMP_SO_FILES} CACHE INTERNAL "")
  set(FLANN_RUNTIME_LIBRARIES_DEBUG ${TMP_SO_FILES_DEBUG} CACHE INTERNAL "")

elseif(UNIX)
  set(FLANN_DIR "/media/zjh/软件/ThirdPartySoftware/Flann/install_res/flann_mini")
  set(FLANN_INCLUDE_PATH "${FLANN_DIR}/include" CACHE INTERNAL "")
  set(FLANN_LIBRARIES 
      "${FLANN_DIR}/lib/Linux/libflann_cpp.so"
      CACHE INTERNAL "")

  set(FLANN_LIBRARIES_DEBUG
      "${FLANN_DIR}/lib/Linux/libflann_cpp.so"
      CACHE INTERNAL "")
endif()

# add the executable
add_executable(${PROJECT_NAME} kdtree.h kdtree.cpp testFlann.cpp)
target_include_directories(${PROJECT_NAME} 
PRIVATE
    ${FLANN_INCLUDE_PATH}
)

target_link_libraries(${PROJECT_NAME}
PUBLIC
    debug ${FLANN_LIBRARIES_DEBUG}
    optimized ${FLANN_LIBRARIES}
)

# Only Windows need copy dll
if(WIN32)

set(DLL_FILES
    ${FLANN_RUNTIME_LIBRARIES}
)

set(DLL_FILES_DEBUG 
    ${FLANN_RUNTIME_LIBRARIES_DEBUG}
)

add_custom_command(
TARGET ${PROJECT_NAME}
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<IF:$<CONFIG:Debug>,${DLL_FILES_DEBUG},${DLL_FILES}>" $<TARGET_FILE_DIR:${PROJECT_NAME}>
COMMAND_EXPAND_LISTS
)
endif()
testFlann.cpp
#pragma once

#include <iostream>
#include <vector>
#include "flann/flann.h"

struct MyPoint3
{
  MyPoint3(double x, double y, double z)
  {
  	this->x = x;
  	this->y = y;
  	this->z = z;
  }
  double x, y, z;
};


int main(int argc, char* argv[])
{
  // a cube vertex
  std::vector<MyPoint3> points;
  points.push_back(MyPoint3(0.0, 0.0, 0.0));
  points.push_back(MyPoint3(1.0, 0.0, 0.0));
  points.push_back(MyPoint3(0.0, 1.0, 0.0));
  points.push_back(MyPoint3(0.0, 0.0, 1.0));
  points.push_back(MyPoint3(1.0, 1.0, 0.0));
  points.push_back(MyPoint3(1.0, 0.0, 1.0));
  points.push_back(MyPoint3(0.0, 1.0, 1.0));
  points.push_back(MyPoint3(1.0, 1.0, 1.0));

  // convert to flann matrix
  flann::Matrix<double> pointMat = flann::Matrix<double>(&points[0].x, static_cast<int>(points.size()), 3);

  //// print
  //for (int i = 0; i < pointMat.rows; ++i) {
  //	for (int j = 0; j < pointMat.cols; ++j) {
  //		std::cout << pointMat[i][j] << " ";
  //	}
  //	std::cout << std::endl;
  //}

  flann::Index<flann::L2<double> > index(pointMat, flann::KDTreeIndexParams(4));
  index.buildIndex();

  // knn
  /*MyPoint3 query = MyPoint3(1.1, 0.8, 0.9);
  flann::Matrix<double> queryMat = flann::Matrix<double>(&query.x, 1, 3);*/

  std::vector<MyPoint3> query;
  query.push_back(MyPoint3(1.1, 0.8, 0.9));
  query.push_back(MyPoint3(-0.0, -0.0, -1.0));
  const int n = query.size();
  flann::Matrix<double> queryMat = flann::Matrix<double>(&query[0].x, n, 3);
  for (int i = 0; i < queryMat.rows; ++i) {
  	for (int j = 0; j < queryMat.cols; ++j) {
  		std::cout << queryMat[i][j] << " ";
  	}
  	std::cout << std::endl;
  }

  const int k = 2;
  /*std::vector<int> idxs(k, 0);
  std::vector<double> dists(k, 0.0);
  flann::Matrix<int> idxMat(&idxs[0], n, k);
  flann::Matrix<double> distMat(&dists[0], n, k);
  index.knnSearch(queryMat, idxMat, distMat, k, flann::SearchParams(32));*/
  std::vector<std::vector<int> > idxs;
  std::vector<std::vector<double> > dists;

  index.knnSearch(queryMat, idxs, dists, k, flann::SearchParams(32));

  std::vector<std::vector<int> > rIdxs;
  std::vector<std::vector<double> > rDists;
  int numNB = index.radiusSearch(queryMat, rIdxs, rDists, 2.0, flann::SearchParams(32));

}

5、KDTree参考资料

kd 树算法之思路篇
kd 树算法之详细篇

posted @   半夜打老虎  阅读(3753)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示