11

opencv flann::Index に問題があります -

インデックスを作成しています

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

その後、ロードして最寄りの近所を見つけようとしています

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

そして、miniflann.cpp にアクセス違反を行ないます。

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

助けてください

4

2 に答える 2

12

Mat()インデックスが格納される場所であるため、flann ファイルを にロードしないでください。コンストラクターが呼び出された後に破棄される一時的なオブジェクトです。そのため、 を呼び出すときにインデックスが有用な場所を指していませんknnSearch()

私は次のことを試しました:

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

その結果:

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

つまり、マトリックスを正しい次元で初期化する必要があります (インデックスに格納されている要素の数が必ずしもわからないため、私には非常にばかげているようです)。

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

トリックを行います。

于 2012-05-10T17:39:32.670 に答える
2

cv::flann::Index受け入れられた答えでは、コンストラクターの入力行列が、保存されたインデックスの生成に使用される行列と同じ次元でなければならない理由が、どういうわけか明確ではなく、誤解を招くものです。@Sau のコメントについて、例を挙げて詳しく説明します。

KDTreeIndex入力として a を使用して生成されcv::Mat sample、保存されました。それをロードするとき、それを生成するために同じマトリックスを提供する必要がありますsample(テンプレート化された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は通常のユークリッド距離です (他のタイプは に記載されていますopencv2/flann/dist.h)。

これで、次のようにインデックスを使用して、点のK最近傍を見つけることができます。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));

マトリックスには、インデックスを生成するために最初に使用されたマトリックス内最近傍の位置indicesが含まれます。そのため、保存されたインデックスを、インデックスの生成に使用されたマトリックスと一緒にロードする必要があります。そうしないと、返されたベクトルに無意味な「最近傍」を指すインデックスが含まれます。 sample

さらにdistances、見つかった近傍がポイントからどれだけ離れているかを含むマトリックスを取得します。これを後で使用して、たとえば逆距離重み付けqueryを実行できます。

また、マトリックスとポイントsample_size全体で一致する必要があることに注意してください。samplequery

于 2016-12-07T09:23:41.293 に答える