|
|
|
|
@ -338,164 +338,134 @@ int GenericIndex<Distance>::radiusSearch(const Mat& query, Mat& indices, Mat& di
|
|
|
|
|
* @deprecated Use GenericIndex class instead
|
|
|
|
|
*/
|
|
|
|
|
template <typename T>
|
|
|
|
|
class
|
|
|
|
|
#ifndef _MSC_VER
|
|
|
|
|
FLANN_DEPRECATED
|
|
|
|
|
#endif
|
|
|
|
|
Index_ {
|
|
|
|
|
class Index_
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
typedef typename L2<T>::ElementType ElementType;
|
|
|
|
|
typedef typename L2<T>::ResultType DistanceType;
|
|
|
|
|
typedef typename L2<T>::ElementType ElementType;
|
|
|
|
|
typedef typename L2<T>::ResultType DistanceType;
|
|
|
|
|
|
|
|
|
|
Index_(const Mat& features, const ::cvflann::IndexParams& params);
|
|
|
|
|
|
|
|
|
|
~Index_();
|
|
|
|
|
|
|
|
|
|
void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& params);
|
|
|
|
|
void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& params);
|
|
|
|
|
|
|
|
|
|
int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& params);
|
|
|
|
|
int radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& params);
|
|
|
|
|
|
|
|
|
|
void save(String filename)
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) nnIndex_L1->save(filename);
|
|
|
|
|
if (nnIndex_L2) nnIndex_L2->save(filename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int veclen() const
|
|
|
|
|
FLANN_DEPRECATED Index_(const Mat& dataset, const ::cvflann::IndexParams& params)
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->veclen();
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->veclen();
|
|
|
|
|
}
|
|
|
|
|
printf("[WARNING] The cv::flann::Index_<T> class is deperecated, use cv::flann::GenericIndex<Distance> instead\n");
|
|
|
|
|
|
|
|
|
|
int size() const
|
|
|
|
|
CV_Assert(dataset.type() == CvType<ElementType>::type());
|
|
|
|
|
CV_Assert(dataset.isContinuous());
|
|
|
|
|
::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
|
|
|
|
|
|
|
|
|
|
if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
|
|
|
|
|
nnIndex_L1 = NULL;
|
|
|
|
|
nnIndex_L2 = new ::cvflann::Index< L2<ElementType> >(m_dataset, params);
|
|
|
|
|
}
|
|
|
|
|
else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
|
|
|
|
|
nnIndex_L1 = new ::cvflann::Index< L1<ElementType> >(m_dataset, params);
|
|
|
|
|
nnIndex_L2 = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
printf("[ERROR] cv::flann::Index_<T> only provides backwards compatibility for the L1 and L2 distances. "
|
|
|
|
|
"For other distance types you must use cv::flann::GenericIndex<Distance>\n");
|
|
|
|
|
CV_Assert(0);
|
|
|
|
|
}
|
|
|
|
|
if (nnIndex_L1) nnIndex_L1->buildIndex();
|
|
|
|
|
if (nnIndex_L2) nnIndex_L2->buildIndex();
|
|
|
|
|
}
|
|
|
|
|
FLANN_DEPRECATED ~Index_()
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->size();
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->size();
|
|
|
|
|
}
|
|
|
|
|
if (nnIndex_L1) delete nnIndex_L1;
|
|
|
|
|
if (nnIndex_L2) delete nnIndex_L2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
::cvflann::IndexParams getParameters()
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->getParameters();
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->getParameters();
|
|
|
|
|
FLANN_DEPRECATED void knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
|
|
|
|
|
{
|
|
|
|
|
::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
|
|
|
|
|
::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
|
|
|
|
|
::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (nnIndex_L1) nnIndex_L1->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
|
|
|
|
|
if (nnIndex_L2) nnIndex_L2->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
|
|
|
|
|
}
|
|
|
|
|
FLANN_DEPRECATED void knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
|
|
|
|
|
{
|
|
|
|
|
CV_Assert(queries.type() == CvType<ElementType>::type());
|
|
|
|
|
CV_Assert(queries.isContinuous());
|
|
|
|
|
::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
|
|
|
|
|
|
|
|
|
|
FLANN_DEPRECATED const ::cvflann::IndexParams* getIndexParameters()
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->getIndexParameters();
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->getIndexParameters();
|
|
|
|
|
}
|
|
|
|
|
CV_Assert(indices.type() == CV_32S);
|
|
|
|
|
CV_Assert(indices.isContinuous());
|
|
|
|
|
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
|
|
|
|
|
|
|
|
|
|
CV_Assert(dists.type() == CvType<DistanceType>::type());
|
|
|
|
|
CV_Assert(dists.isContinuous());
|
|
|
|
|
::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
|
|
|
|
|
|
|
|
|
|
if (nnIndex_L1) nnIndex_L1->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
|
|
|
|
|
if (nnIndex_L2) nnIndex_L2->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLANN_DEPRECATED int radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
|
|
|
|
|
{
|
|
|
|
|
::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
|
|
|
|
|
::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
|
|
|
|
|
::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
|
|
|
|
|
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLANN_DEPRECATED int radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
|
|
|
|
|
{
|
|
|
|
|
CV_Assert(query.type() == CvType<ElementType>::type());
|
|
|
|
|
CV_Assert(query.isContinuous());
|
|
|
|
|
::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
|
|
|
|
|
|
|
|
|
|
CV_Assert(indices.type() == CV_32S);
|
|
|
|
|
CV_Assert(indices.isContinuous());
|
|
|
|
|
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
|
|
|
|
|
|
|
|
|
|
CV_Assert(dists.type() == CvType<DistanceType>::type());
|
|
|
|
|
CV_Assert(dists.isContinuous());
|
|
|
|
|
::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
|
|
|
|
|
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLANN_DEPRECATED void save(String filename)
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) nnIndex_L1->save(filename);
|
|
|
|
|
if (nnIndex_L2) nnIndex_L2->save(filename);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLANN_DEPRECATED int veclen() const
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->veclen();
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->veclen();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLANN_DEPRECATED int size() const
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->size();
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->size();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLANN_DEPRECATED ::cvflann::IndexParams getParameters()
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->getParameters();
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->getParameters();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FLANN_DEPRECATED const ::cvflann::IndexParams* getIndexParameters()
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->getIndexParameters();
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->getIndexParameters();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// providing backwards compatibility for L2 and L1 distances (most common)
|
|
|
|
|
::cvflann::Index< L2<ElementType> >* nnIndex_L2;
|
|
|
|
|
::cvflann::Index< L1<ElementType> >* nnIndex_L1;
|
|
|
|
|
// providing backwards compatibility for L2 and L1 distances (most common)
|
|
|
|
|
::cvflann::Index< L2<ElementType> >* nnIndex_L2;
|
|
|
|
|
::cvflann::Index< L1<ElementType> >* nnIndex_L1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
template <typename T>
|
|
|
|
|
class FLANN_DEPRECATED Index_;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//! @cond IGNORED
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
Index_<T>::Index_(const Mat& dataset, const ::cvflann::IndexParams& params)
|
|
|
|
|
{
|
|
|
|
|
printf("[WARNING] The cv::flann::Index_<T> class is deperecated, use cv::flann::GenericIndex<Distance> instead\n");
|
|
|
|
|
|
|
|
|
|
CV_Assert(dataset.type() == CvType<ElementType>::type());
|
|
|
|
|
CV_Assert(dataset.isContinuous());
|
|
|
|
|
::cvflann::Matrix<ElementType> m_dataset((ElementType*)dataset.ptr<ElementType>(0), dataset.rows, dataset.cols);
|
|
|
|
|
|
|
|
|
|
if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L2 ) {
|
|
|
|
|
nnIndex_L1 = NULL;
|
|
|
|
|
nnIndex_L2 = new ::cvflann::Index< L2<ElementType> >(m_dataset, params);
|
|
|
|
|
}
|
|
|
|
|
else if ( ::cvflann::flann_distance_type() == cvflann::FLANN_DIST_L1 ) {
|
|
|
|
|
nnIndex_L1 = new ::cvflann::Index< L1<ElementType> >(m_dataset, params);
|
|
|
|
|
nnIndex_L2 = NULL;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
printf("[ERROR] cv::flann::Index_<T> only provides backwards compatibility for the L1 and L2 distances. "
|
|
|
|
|
"For other distance types you must use cv::flann::GenericIndex<Distance>\n");
|
|
|
|
|
CV_Assert(0);
|
|
|
|
|
}
|
|
|
|
|
if (nnIndex_L1) nnIndex_L1->buildIndex();
|
|
|
|
|
if (nnIndex_L2) nnIndex_L2->buildIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
Index_<T>::~Index_()
|
|
|
|
|
{
|
|
|
|
|
if (nnIndex_L1) delete nnIndex_L1;
|
|
|
|
|
if (nnIndex_L2) delete nnIndex_L2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
void Index_<T>::knnSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, int knn, const ::cvflann::SearchParams& searchParams)
|
|
|
|
|
{
|
|
|
|
|
::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
|
|
|
|
|
::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
|
|
|
|
|
::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
|
|
|
|
|
|
|
|
|
|
if (nnIndex_L1) nnIndex_L1->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
|
|
|
|
|
if (nnIndex_L2) nnIndex_L2->knnSearch(m_query,m_indices,m_dists,knn,searchParams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
void Index_<T>::knnSearch(const Mat& queries, Mat& indices, Mat& dists, int knn, const ::cvflann::SearchParams& searchParams)
|
|
|
|
|
{
|
|
|
|
|
CV_Assert(queries.type() == CvType<ElementType>::type());
|
|
|
|
|
CV_Assert(queries.isContinuous());
|
|
|
|
|
::cvflann::Matrix<ElementType> m_queries((ElementType*)queries.ptr<ElementType>(0), queries.rows, queries.cols);
|
|
|
|
|
|
|
|
|
|
CV_Assert(indices.type() == CV_32S);
|
|
|
|
|
CV_Assert(indices.isContinuous());
|
|
|
|
|
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
|
|
|
|
|
|
|
|
|
|
CV_Assert(dists.type() == CvType<DistanceType>::type());
|
|
|
|
|
CV_Assert(dists.isContinuous());
|
|
|
|
|
::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
|
|
|
|
|
|
|
|
|
|
if (nnIndex_L1) nnIndex_L1->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
|
|
|
|
|
if (nnIndex_L2) nnIndex_L2->knnSearch(m_queries,m_indices,m_dists,knn, searchParams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
int Index_<T>::radiusSearch(const std::vector<ElementType>& query, std::vector<int>& indices, std::vector<DistanceType>& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
|
|
|
|
|
{
|
|
|
|
|
::cvflann::Matrix<ElementType> m_query((ElementType*)&query[0], 1, query.size());
|
|
|
|
|
::cvflann::Matrix<int> m_indices(&indices[0], 1, indices.size());
|
|
|
|
|
::cvflann::Matrix<DistanceType> m_dists(&dists[0], 1, dists.size());
|
|
|
|
|
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
|
int Index_<T>::radiusSearch(const Mat& query, Mat& indices, Mat& dists, DistanceType radius, const ::cvflann::SearchParams& searchParams)
|
|
|
|
|
{
|
|
|
|
|
CV_Assert(query.type() == CvType<ElementType>::type());
|
|
|
|
|
CV_Assert(query.isContinuous());
|
|
|
|
|
::cvflann::Matrix<ElementType> m_query((ElementType*)query.ptr<ElementType>(0), query.rows, query.cols);
|
|
|
|
|
|
|
|
|
|
CV_Assert(indices.type() == CV_32S);
|
|
|
|
|
CV_Assert(indices.isContinuous());
|
|
|
|
|
::cvflann::Matrix<int> m_indices((int*)indices.ptr<int>(0), indices.rows, indices.cols);
|
|
|
|
|
|
|
|
|
|
CV_Assert(dists.type() == CvType<DistanceType>::type());
|
|
|
|
|
CV_Assert(dists.isContinuous());
|
|
|
|
|
::cvflann::Matrix<DistanceType> m_dists((DistanceType*)dists.ptr<DistanceType>(0), dists.rows, dists.cols);
|
|
|
|
|
|
|
|
|
|
if (nnIndex_L1) return nnIndex_L1->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
|
|
|
|
if (nnIndex_L2) return nnIndex_L2->radiusSearch(m_query,m_indices,m_dists,radius,searchParams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//! @endcond
|
|
|
|
|
|
|
|
|
|
/** @brief Clusters features using hierarchical k-means algorithm.
|
|
|
|
|
|
|
|
|
|
|