標籤:opencv k-d樹 flann
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;
}
實驗結果:
OpenCV K-d樹實現之FLANN (Fast Library for Approximate Nearest Neighbors) 演算法實現及解析