您的位置:首页 > 移动开发

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

2015-01-08 10:00 453 查看
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;

}

实验结果:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: