2012-04-26 17 views
11

tengo algunos problemas con OpenCV flann :: Índice -Cómo usar opencv flann :: Index?

estoy creando índice

Mat samples = Mat::zeros(vfv_net_quie.size(),24,CV_32F); 
     for (int i =0; i < vfv_net_quie.size();i++) 
     { 
      for (int j = 0;j<24;j++) 
      { 
       samples.at<float>(i,j)=(float)vfv_net_quie[i].vfv[j]; 
      } 
     } 
    cv::flann::Index flann_index(
      samples, 
      cv::flann::KDTreeIndexParams(4), 
      cvflann::FLANN_DIST_EUCLIDEAN 
       ); 
    flann_index.save("c:\\index.fln"); 

D espués de que yo estoy tratando de cargarla y encontrar neiborhoods cercanos

cv::flann::Index flann_index(Mat(), 
    cv::flann::SavedIndexParams("c:\\index.fln"), 
    cvflann::FLANN_DIST_EUCLIDEAN 
    ); 

cv::Mat resps(vfv_reg_quie.size(), K, CV_32F); 
cv::Mat nresps(vfv_reg_quie.size(), K, CV_32S); 
cv::Mat dists(vfv_reg_quie.size(), K, CV_32F); 

flann_index.knnSearch(sample,nresps,dists,K,cv::flann::SearchParams(64)); 

Y tiene una infracción de acceso en miniflann.cpp en la línea

((IndexType*)index)->knnSearch(_query, _indices, _dists, knn, 
          (const ::cvflann::SearchParams&)get_params(params)); 

Pl easy help

Respuesta

12

No debe cargar el archivo de flandes en un Mat(), ya que es el lugar donde se almacena el índice. Es un objeto temporal destruido después de que se llamó al constructor. Es por eso que el índice no está apuntando a ningún lugar útil cuando llamas al knnSearch().

me trataron siguiente:

cv::Mat indexMat; 
cv::flann::Index flann_index(
    indexMat, 
    cv::flann::SavedIndexParams("c:\\index.fln"), 
    cvflann::FLANN_DIST_EUCLIDEAN 
); 

lo que resulta en:

Reading FLANN index error: the saved data size (100, 64) or type (5) is different from the passed one (0, 0), 0 

lo que significa, que la matriz tiene que ser inicializado con las dimensiones correctas (parece muy estúpido para mí, como yo no' t necesariamente saber, cuántos elementos están almacenados en mi índice).

cv::Mat indexMat(samples.size(), CV_32FC1); 
cv::flann::Index flann_index(
    indexMat, 
    cv::flann::SavedIndexParams("c:\\index.fln"), 
    cvflann::FLANN_DIST_EUCLIDEAN 
); 

hace el truco.

+4

Un punto a tener en cuenta es que debe proporcionar el conjunto de datos original real, no solo un tapete con las dimensiones correctas. No está muy claro en la documentación de OpenCV, pero se menciona en la Sección 3.3.4 de la [documentación de flandes] (http://www.cs.ubc.ca/~mariusm/uploads/FLANN/flann_manual-1.6.pdf) – Sau

+0

@Sau no es la Sección 3.3.4 hablando de Matlab y no de C++? ¿Ha verificado su comentario en OpenCV o en la versión C++ de flann? – t2k32316

1

En la respuesta aceptada, de alguna manera no está claro y es engañoso por qué la matriz de entrada en el constructor cv::flann::Index debe tener la misma dimensión que la matriz utilizada para generar el índice guardado. Voy a elaborar sobre el comentario de @Sau con un ejemplo.

KDTreeIndex se generó usando como entrada un cv::Mat sample, y luego se guardó. Cuando se carga, debe proporcionar la misma sample matriz para generarlo, algo así como (usando la interfaz de plantilla GenericIndex):

cv::Mat sample(sample_num, sample_size, ... /* other params */); 
cv::flann::SavedIndexParams index_params("c:\\index.fln"); 
cv::flann::GenericIndex<cvflann::L2<float>> flann_index(sample, index_params); 

L2 es la distancia euclídea habitual (otros tipos se pueden encontrar en opencv2/flann/dist.h).

Ahora el índice puede ser utilizado como muestra el encontrar los K vecinos más cercanos de un punto query:

std::vector<float> query(sample_size); 
std::vector<int> indices(K); 
std::vector<float> distances(K); 

flann_index.knnSearch(query, indices, distances, K, cv::flann::SearchParams(64)); 

La matriz indices contendrá los lugares de los vecinosmás cercanos en la matriz sample, que se usó al principio para generar el índice. Es por eso que debe cargar el índice guardado con la matriz utilizada para generar el índice, de lo contrario, el vector devuelto contendrá índices que apuntan a "vecinos más cercanos" sin sentido.

Además, obtiene una matriz distances que contiene qué tan lejos están los vecinos encontrados de su punto query, que luego puede usar para realizar algunos inverse distance weighting, por ejemplo.

Tenga en cuenta también que sample_size tiene que coincidir en sample matriz y query punto.