NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const std::string& filename, Distance distance) { typedef typename Distance::ElementType ElementType; FILE* fin = fopen(filename.c_str(), "rb"); if (fin == NULL) { return NULL; } IndexHeader header = load_header(fin); if (header.data_type != flann_datatype<ElementType>::value) { throw FLANNException("Datatype of saved index is different than of the one to be created."); } // We cannot make this check now, because the index and the dataset might be of different size // some entries of the dataset might not be used in the index /* if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) { throw FLANNException("The index saved belongs to a different dataset"); } */ IndexParams params; params["algorithm"] = header.index_type; NNIndex<Distance>* nnIndex = create_index_by_type<Distance>(dataset, params, distance); nnIndex->loadIndex(fin); fclose(fin); return nnIndex; }
void save_header(FILE* stream, const NNIndex& index) { IndexHeader header; memset(header.signature, 0 , sizeof(header.signature)); strcpy(header.signature, FLANN_SIGNATURE); header.flann_version = (int)FLANN_VERSION; header.index_type = index.getType(); header.rows = index.size(); header.cols = index.veclen(); std::fwrite(&header, sizeof(header),1,stream); }
EXPORTED FLANN_INDEX flann_build_index(float* dataset, int rows, int cols, float* speedup, FLANNParameters* flann_params) { try { if (flann_params == NULL) { throw FLANNException("The index_params agument must be non-null"); } init_flann_parameters(flann_params); DatasetPtr inputData = new Dataset<float>(rows,cols,dataset); float target_precision = flann_params->target_precision; NNIndex* index = NULL; if (flann_params->target_precision < 0) { Params params = parametersToParams(*flann_params); logger.info("Building index\n"); index = create_index((flann_algorithm_t)(int)params["algorithm"],*inputData,params); StartStopTimer t; t.start(); index->buildIndex(); t.stop(); logger.info("Building index took: %g\n",t.value); } else { if (flann_params->build_weight < 0) { throw FLANNException("The index_params.build_weight must be positive."); } if (flann_params->memory_weight < 0) { throw FLANNException("The index_params.memory_weight must be positive."); } Autotune autotuner(flann_params->build_weight, flann_params->memory_weight, flann_params->sample_fraction); Params params = autotuner.estimateBuildIndexParams(*inputData, target_precision); index = create_index((flann_algorithm_t)(int)params["algorithm"],*inputData,params); index->buildIndex(); autotuner.estimateSearchParams(*index,*inputData,target_precision,params); paramsToParameters(params, flann_params); if (speedup != NULL) { *speedup = float(params["speedup"]); } } return index; } catch (runtime_error& e) { logger.error("Caught exception: %s\n",e.what()); return NULL; } }
NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const cv::String& filename, Distance distance) { typedef typename Distance::ElementType ElementType; FILE* fin = fopen(filename.c_str(), "rb"); if (fin == NULL) { return NULL; } IndexHeader header = load_header(fin); /*if (header.data_type != Datatype<ElementType>::type()) { throw FLANNException("Datatype of saved index is different than of the one to be created."); } if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) { throw FLANNException("The index saved belongs to a different dataset"); }*/ IndexParams params; params["algorithm"] = header.index_type; NNIndex<Distance>* nnIndex = create_index_by_type<Distance>(dataset, params, distance); nnIndex->loadIndex(fin); fclose(fin); return nnIndex; }
float search_with_ground_truth(NNIndex& index, const Matrix<float>& inputData, const Matrix<float>& testData, const Matrix<int>& matches, int nn, int checks, float& time, float& dist, int skipMatches) { if (matches.cols<nn) { logger.info("matches.cols=%d, nn=%d\n",matches.cols,nn); throw FLANNException("Ground truth is not computed for as many neighbors as requested"); } KNNResultSet resultSet(nn+skipMatches); SearchParams searchParams(checks); int correct = 0; float distR = 0; StartStopTimer t; int repeats = 0; while (t.value<0.2) { repeats++; t.start(); correct = 0; distR = 0; for (int i = 0; i < testData.rows; i++) { float* target = testData[i]; resultSet.init(target, testData.cols); index.findNeighbors(resultSet,target, searchParams); int* neighbors = resultSet.getNeighbors(); neighbors = neighbors+skipMatches; correct += countCorrectMatches(neighbors,matches[i], nn); distR += computeDistanceRaport(inputData, target,neighbors,matches[i], testData.cols, nn); } t.stop(); } time = (float)(t.value/repeats); float precicion = (float)correct/(nn*testData.rows); dist = distR/(testData.rows*nn); logger.info("%8d %10.4g %10.5g %10.5g %10.5g\n", checks, precicion, time, 1000.0 * time / testData.rows, dist); return precicion; }
void search_for_neighbors(NNIndex& index, const Matrix<float>& testset, Matrix<int>& result, Matrix<float>& dists, const SearchParams& searchParams, int skip) { assert(testset.rows == result.rows); int nn = result.cols; KNNResultSet resultSet(nn+skip); for (int i = 0; i < testset.rows; i++) { float* target = testset[i]; resultSet.init(target, testset.cols); index.findNeighbors(resultSet,target, searchParams); int* neighbors = resultSet.getNeighbors(); float* distances = resultSet.getDistances(); memcpy(result[i], neighbors+skip, nn*sizeof(int)); memcpy(dists[i], distances+skip, nn*sizeof(float)); } }