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 樹算法之詳細篇


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM