Opencv高速線形検索knnsearchとknnmatchの比較
6880 ワード
Opencvのflannおよびmatchのライブラリを用いて線形近隣knn検索の速度テストを行った結果、knnmatchはより速く、opencvの下位コードを見て、knnmatchはparallel_を使用した.for_ へいれつかそく
#include
#include
#include
#include
using namespace cv;
using namespace std;
const int samples = 50000;
const int DIM = 1024;
const int k =10;
inline double cpu_time(){
return clock()*1000/CLOCKS_PER_SEC;
}
void generate_data(Mat& data){
RNG rng((unsigned int)time(NULL));
data.create(samples,DIM,CV_32FC1);
Point center;
center.x = rng.uniform(0,data.cols);
center.y = rng.uniform(0,data.rows);
rng.fill(data, RNG::NORMAL, Scalar(center.x,center.y), Scalar(data.cols*0.05,data.rows*0.05));
}
void linear_search(const Mat& data, const Mat& point, Mat& indices, Mat& dists, const int k){
double t1,t2;
flann::Index flannIndex(data, flann::LinearIndexParams(), cvflann::FLANN_DIST_L2);
cout<<"Begin LinearSearch: "<64));
t2 = cpu_time();
cout<<"Finish linerSearch: "<"ms"<float calculate(float* a, float* b, int size, float worst_dist = -1){
float diff0,diff1,diff2,diff3,result=0;
float* last = a + size;
float* lastgroup = last-3;
while (a < lastgroup)
{
diff0 = a[0]-b[0];
diff1 = a[1]-b[1];
diff2 = a[2]-b[2];
diff3 = a[3]-b[3];
result += diff0*diff0 + diff1*diff1 + diff2*diff2 + diff3*diff3;
a+=4;
b+=4;
if ((worst_dist>0)&&(result>worst_dist))
{
return result;
}
}
while (areturn result;
}
//My test with loop unrolling, as it is one of the most expensive inner loops
void test(float* a, float* b){
double t1,t2;
t1 = cpu_time();
cout<<"Begin test: "<float* data = a;
float done=0;
for(int i=0; icout<<"Finish test: "<"ms"<//Brute Force Matcher
void BFM(Mat& data, Mat& point){
double t1, t2;
Ptr DM = DescriptorMatcher::create("BruteForce");
vector<vector > matches;
cout<<"Begin BFM: "<knnMatch(point,data,matches,k);
t2 = cpu_time();
cout<<"Finish BFM: "<"ms"<for (int i=0;icout<0][i].trainIdx<<", ";
}
cout<int main(){
Mat data;
generate_data(data);
Mat point = data.row(10).clone();
float* a = (float* )data.data;
float* b = (float* )point.data;
test(a,b);
Mat indices(1,DIM,CV_32FC1);
Mat dists(1,DIM,CV_32FC1);
BFM(data,point);
linear_search(data,point,indices,dists,k);
cout<return 0;
}