2012-04-26 41 views
11

Tôi có một số vấn đề với opencv Flann :: Index -Làm thế nào để sử dụng opencv flann :: Index?

tôi là tạo ra chỉ số

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"); 

Một fter rằng tôi tryin để tải nó và tìm neiborhoods gần

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)); 

Và có vi phạm quyền truy cập trong miniflann.cpp trong dòng

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

Pl trợ giúp dễ dàng

Trả lời

12

Bạn không nên nạp tệp flann vào Mat(), vì đây là nơi lưu trữ chỉ mục. Nó là một đối tượng tạm thời bị phá hủy sau khi hàm tạo được gọi. Đó là lý do tại sao chỉ mục không trỏ tới bất kỳ nơi nào hữu ích khi bạn gọi knnSearch().

tôi đã cố gắng sau:

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

kết quả là:

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

điều đó có nghĩa, rằng ma trận phải được khởi tạo với kích thước chính xác (có vẻ rất ngu ngốc với tôi, như tôi don' t nhất thiết phải biết, có bao nhiêu phần tử được lưu trữ trong chỉ mục của tôi).

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

thực hiện thủ thuật.

+4

Một điểm cần lưu ý là bạn cần cung cấp tập dữ liệu gốc thực tế, không chỉ là một Mat có kích thước phù hợp. Nó không rõ ràng trong tài liệu OpenCV, nhưng được đề cập trong Phần 3.3.4 của [tài liệu flann] (http://www.cs.ubc.ca/~mariusm/uploads/FLANN/flann_manual-1.6.pdf) – Sau

+0

@Sau không phải là Phần 3.3.4 nói về Matlab chứ không phải C++? Bạn đã xác minh nhận xét của bạn trong OpenCV hoặc trong phiên bản C++ của flann? – t2k32316

1

Trong câu trả lời được chấp nhận bằng cách nào đó không rõ ràng và gây hiểu lầm tại sao ma trận đầu vào trong hàm tạo cv::flann::Index phải có cùng kích thước với ma trận được sử dụng để tạo chỉ mục đã lưu. Tôi sẽ giải thích về bình luận của @ Sáu với một ví dụ.

KDTreeIndex được tạo bằng cách sử dụng làm đầu vào cv::Mat sample và sau đó được lưu. Khi bạn tải nó, bạn phải cung cấp cùng sample ma trận để tạo ra nó, một cái gì đó tương tự (sử dụng giao diện templated 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 là khoảng cách Euclide thông thường (loại khác có thể được tìm thấy trong opencv2/flann/dist.h).

Bây giờ chỉ số có thể được sử dụng như các tìm K láng giềng gần nhất của một điểm 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)); 

Ma trận indices sẽ chứa địa điểm của láng giềng gần nhấttrong ma trận sample, được sử dụng lúc đầu để tạo chỉ mục. Đó là lý do tại sao bạn cần tải chỉ mục đã lưu với ma trận rất được sử dụng để tạo chỉ mục, nếu không vectơ trả lại sẽ chứa các chỉ mục trỏ đến "hàng xóm gần nhất" vô nghĩa.

Ngoài ra, bạn nhận được ma trận distances chứa khoảng cách hàng xóm được tìm thấy từ điểm query của bạn, ví dụ sau này bạn có thể sử dụng để thực hiện một số inverse distance weighting.

Cũng xin lưu ý rằng sample_size phải khớp với trên sample ma trận và query điểm.

Các vấn đề liên quan