OpenCV K-d树实现之FLANN (Fast Library for Approximate Nearest Neighbors) 算法实现及解析

k-d树搜索最近点,在opencv中使用FLANN算法,其包含:

1:建树   2.查询

程序见下:

#include "kdtree.h"

#include <iostream>

#include <iomanip>

#include "cv.h"

#include "highgui.h"

#include <fstream>

#include "cv.h"

#include "highgui.h"

#include <vector>    // <vector > STL头文件

#include <stdio.h>

#include "opencv2/objdetect/objdetect.hpp"

#include "opencv2/features2d/features2d.hpp"

#include "opencv2/highgui/highgui.hpp"

#include "opencv2/calib3d/calib3d.hpp"

#include "opencv2/imgproc/imgproc_c.h"

#include <iostream>

#define EXAMPLAR_NUM 700

#define EXAMPLAR_DIM 3

/****系统可以搜索660个3维点云中的最近点****/

/************保存CvMat型矩阵****************************

输入参数:&VecString:n个点云容器

输出参数:*Matri:转换成对应的3*n矩阵

*************************************************************/

void SaveCvmatToTXT(const CvMat*Matri, const char* filename)

{

std::ofstream  file(filename);  //保存文件

for (int i = 0; i<Matri->rows; i++)

{

for (int j = 0; j<Matri->cols; j++)

{

file << "    " << cvmGet(Matri, i, j);

}

file << std::endl;

}

file.close();

}

/***********读取txt文档保存CvMat型矩阵****************************

输入参数:&VecString:n个点云容器

输出参数:*Matri:转换成对应的3*n矩阵

***************************************************************/

void ReadTxtToCvmat(CvMat*Matri, const char* filename)

{

std::ifstream  file(filename);  //保存文件

double temp;

for (int i = 0; i<Matri->rows; i++)

{

for (int j = 0; j<Matri->cols; j++)

{

file >> temp;

cvmSet(Matri, i, j,temp);

}

}

file.close();

}

int main(int argc, char *argv[])

{

cv::Mat target(10, 3, CV_32F);  //目标点云(用之构建k-d树

ReadTxtToCvmat(&(CvMat)target, "data.txt");

std::cout << "target"<<target<< std::endl;

//1)创建查询树 :(此处构建K-d树)

cv::flann::KDTreeIndexParams indexParams(4);//(此参数用来设置构建的数据结构,此处选择K-d树)

cv::flann::Index kdtree(target, indexParams);//此处用target构建k-d树

//2) 查找 :

/*cv::Point3f pt ;

std::cout << "Input target point:" << std::endl;

std::cin >> pt.x  >> pt.y >> pt.z;

std::vector<float> query;

query.push_back(pt.x);

query.push_back(pt.y);

query.push_back(pt.z);*/  //可用来手动输入单个要搜索的原始点

cv::Mat source= target;    //原始点

cv::Mat neibours(source.rows, source.cols, CV_32F);//存储搜索到的点

int k =1; //number of nearest neighbors

cv::Mat indices(source.rows, k, CV_32F);   //装载搜索到的对应点的索引(即neibours在target这个矩阵的行数)

cv::Mat dists(source.rows,k,CV_32F);         //搜索到的最近邻的距离

kdtree.knnSearch(source, indices, dists, k, cv::flann::SearchParams(32));

//std::cout << indices.at<int>(9, 0) << std::endl;

//std::cout << dists.at<float>(9,0) << std::endl;

for (int i = 0; i < neibours.rows; i++)

{

neibours.row(i) = target.row(indices.at<int>(i, 0)) + 0;

}

std::cout << "source=" << source << std::endl;

std::cout << "neibours" << neibours << std::endl;

std::cout << "indices=" << indices << std::endl;

std::cout << "dists=" << dists << std::endl;

system("PAUSE");

return 0;

}

实验结果:

时间: 2024-07-31 09:43:32

OpenCV K-d树实现之FLANN (Fast Library for Approximate Nearest Neighbors) 算法实现及解析的相关文章

快速近似最近邻搜索库 FLANN - Fast Library for Approximate Nearest Neighbors

What is FLANN? FLANN is a library for performing fast approximate nearest neighbor searches in high dimensional spaces. It contains a collection of algorithms we found to work best for nearest neighbor search and a system for automatically choosing t

[C++与机器学习] k-近邻算法(K–nearest neighbors)

C++ with Machine Learning -K–nearest neighbors 我本想写C++与人工智能,但是转念一想,人工智能范围太大了,我根本介绍不完也没能力介绍完,所以还是取了他的子集.我想这应该是一个有关机器学习的系列文章,我会不定期更新文章,希望喜欢机器学习的朋友不宁赐教. 本系列特别之处是与一些实例相结合来系统的讲解有关机器学习的各种算法,由于能力和时间有限,不会向诸如Simon Haykin<<NEURAL NETWORKS>>等大块头详细的讲解某一个领

K Nearest Neighbor 算法

K Nearest Neighbor算法又叫KNN算法,这个算法是机器学习里面一个比较经典的算法, 总体来说KNN算法是相对比较容易理解的算法.其中的K表示最接近自己的K个数据样本.KNN算法和K-Means算法不同的是,K-Means算法用来聚类,用来判断哪些东西是一个比较相近的类型,而KNN算法是用来做归类的,也就是说,有一个样本空间里的样本分成很几个类型,然后,给定一个待分类的数据,通过计算接近自己最近的K个样本来判断这个待分类数据属于哪个分类.你可以简单的理解为由那离自己最近的K个点来投

【BZOJ 1901】【Zju 2112】 Dynamic Rankings 动态K值 树状数组套主席树模板题

达神题解传送门:http://blog.csdn.net/dad3zz/article/details/50638360 说一下我对这个模板的理解: 看到这个方法很容易不知所措,因为动态K值需要套树状数组,而我一开始根本不知道该怎么套,, 学习吧,,, 然后我自己脑补如果不套会如何?后来想到是查询O(logn),修改是O(nlogn),很明显修改的复杂度太大了,为了降低修改的复杂度,我们只得套上树状数组来维护前缀和使它的n的复杂度降低为logn,从而修改的复杂度变为O(log2n).但因为我们套

HDU 5412 CRB and Queries(区间第K大 树套数 按值建树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5412 Problem Description There are N boys in CodeLand. Boy i has his coding skill Ai. CRB wants to know who has the suitable coding skill. So you should treat the following two types of queries. Query 1:

opencv K邻近分类器的使用

下面是手册中给出的K邻近分类器使用的例子,该例子是以CvMat形式实现的.通过下面的例子可以知道如何使用Opencv自带的分类器.矩阵数据如何访问.如何画图.如何使用Opencv的随机数生成函数等内容.在第二个例子中已将这些代码部分做了注释. #include "ml.h" #include "highgui.h" int main( int argc, char** argv ) { const int K = 10; int i, j, k, accuracy;

BZOJ 1901 Zju 2112 Dynamic Rankings 动态维护第k小 树套树

题目大意:动态维护第k小. 思路:线段树套treap,裸题,就是不怎么好写. CODE: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 50010 #define INF 1e9 #define LEFT (pos << 1) #define RIGHT (pos << 1|1) #define SIZ

静态区间第k大 树套树解法

然而过不去你谷的模板 思路: 值域线段树\([l,r]\)代表一棵值域在\([l,r]\)范围内的点构成的一颗平衡树 平衡树的\(BST\)权值为点在序列中的位置 查询区间第\(k\)大值时 左区间在\([l,r]\)范围内的树的大小与\(k\)比较 大了进去,小了减掉换一边 关于建树 递归建估计是\(O(nlog^2n)\)的 Code: #include <cstdio> #include <cstdlib> #include <algorithm> #includ

UVALive 7148 LRIP 14年上海区域赛K题 树分治

题意 n个点组成一棵树, 带有点权. 求最长不降的路径的长度, 且路径上最大值最小值之差不超过D. 显然是树分治, 但是分治之后如何维护答案呢. 假设当前重心为g, 分别记录g出发不降路径的长度,以及最大值, 和不升路径的长度以及最小值. 这里用到一个map和二分, 线段树也可以, 但是如果用线段树还要考虑负值, 再加上线段树的clear以及稍微暴力的查询.  常数大小不好说. 1 #include <bits/stdc++.h> 2 using namespace std; 3 typede