前言
本博客主要包括 利用 opencv 的最近邻搜索. 示例中包括 对一个点和对多个点的.
同时附带了自己目前经常用的Cmake 文件, 以及一个 python opencv 显示深度图的示例.
主要参考的网址有
OpenCV——KD Tree(介绍完整的flann邻近搜索)
opencv官网
主要的示例代码
#include<opencv2/flann/miniflann.hpp>
#include<iostream>
#include<vector>
using namespace std;
int main(){
/*
* vector<cv::Point2f> m_pOriPtXY={ cv::Point2f(1,1), cv::Point2f(2,2),
cv::Point2f(3,3), cv::Point2f(4,4), cv::Point2f(5,5), cv::Point2f(2,4)};
* */
vector<cv::Point2f> features={{1,1}, {2, 2}, {3, 3}, {4, 4}, {2, 4}};
vector<cv::Point2f> raw_queries={{0,0}, {3, 4}, {4, 3}};
/**建立kd树索引**/
cv::Mat source = cv::Mat(features).reshape(1);
//cout<<source.size()<<endl;
source.convertTo(source, CV_32F);
//cout<<source.size()<<endl;
// 注意这里其实最后还是转到一个 Mat 上 Mat 的大小是 n * p_dim [下面输出的size 是 先 width, 然后height]
// 原本的意思是建立个新的地址进行转换
cv::Mat queries = cv::Mat(raw_queries);
//cout<<queries.size()<<endl; // 1 x 3
queries = queries.reshape(1);
//cout<<queries.size()<<endl; // 2 x 3
queries.convertTo(queries, CV_32F)
//cout<<queries.size()<<endl; // 2 x 3
cv::flann::KDTreeIndexParams indexParams(2);
cv::flann::Index kdtree(source, indexParams); //此部分建立kd-tree索引同上例,故不做详细叙述
/**预设knnSearch所需参数及容器**/
unsigned queryNum = 2;//用于设置返回邻近点的个数
vector<float> vecQuery(2);//存放 查询点 的容器(本例都是vector类型)
vector<int> vecIndex(queryNum);//存放返回的点索引
vector<float> vecDist(queryNum);//存放距离
cv::flann::SearchParams params(32);//设置knnSearch搜索参数
/**KD树knn查询**/
vecQuery = {2.5, 2.6};
kdtree.knnSearch(vecQuery, vecIndex, vecDist, queryNum, params);
//请注意这句的逻辑:由先前生成的kdtree索引对象调用knnSearch()函数,进行点的knn搜索
cv::Mat indices;
cv::Mat dists;
kdtree.knnSearch(queries, indices, dists, 1, params);
cout<<"vecDist: "<<endl;
for(auto&x :vecDist){
cout<<x<<" ";
}
cout<<endl;
cout<<"vecIndex: "<<endl;
for(auto&x :vecIndex){
cout<<x<<" ";
}
cout<<endl;
cout<<indices<<endl; // 0 based
cout<<dists<<endl; // pow
return 0;
}
自己简单的CMake 模板
├── CMakeLists.txt
└── src/ # code in
cmake_minimum_required(VERSION 2.8)
set(targetname test_ocv)
PROJECT(${targetname})
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# #####
if(CMAKE_COMPILER_IS_GNUCC)
add_definitions(-std=c++11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -O3")
endif(CMAKE_COMPILER_IS_GNUCC)
# #####
#######
if(DEFINED _chj_libs)
else()
set(_chj_libs "")
endif()
IF (WIN32)
include(xxxxxx/opencv3.1/OpenCVConfig.cmake)
ELSEIF (APPLE)
MESSAGE(STATUS "Now is Apple systens.")
ELSEIF (UNIX)
FIND_PACKAGE(OpenCV 3)
ENDIF ()
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
LINK_DIRECTORIES(${OPENCV_LIB_DIR})
LIST(APPEND _chj_libs opencv_core opencv_highgui opencv_imgproc opencv_calib3d opencv_imgcodecs )
######
file(GLOB_RECURSE CURRENT_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h)
source_group("Include" FILES ${CURRENT_HEADERS})
file(GLOB_RECURSE Source ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
source_group("Source" FILES ${Source})
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/src
)
ADD_EXECUTABLE(main ${Source})
target_link_libraries(main ${_chj_libs} )
显示深度图
今天才知道不用plt, ocv也能做很多事情
with open(fdepth, "rb") as fp:
raw = np.fromfile(fp, np.float32, h*w*3).reshape(h, w, 3)
raw = raw[:, :,2]
raw[raw>2000]=0 # 去掉背景
cv.normalize(raw, raw, 0,255, cv.NORM_MINMAX)
#p(raw.dtype)
raw=raw.astype(np.uint8)
#p(raw.dtype)
#new_raw=raw.copy()
raw = cv.applyColorMap(raw, cv.COLORMAP_JET)