0

VlFeat の SIFT 実装を機能させることができたので、2 つの画像記述子のセットを一致させたいと思います。

std::vectorSIFT の特徴ベクトルは 128 要素の float 配列です。以下のスニペットに示すように、記述子リストを s に格納しました。

std::vector<std::vector<float> > ldescriptors = leftImage->descriptors;
std::vector<std::vector<float> > rdescriptors = rightImage->descriptors;

/* KDTree, L1 comparison metric, dimension 128, 1 tree, L1 metric */
VlKDForest* forest = vl_kdforest_new(VL_TYPE_FLOAT, 128, 1, VlDistanceL1);

/* Build the tree from the left descriptors */
vl_kdforest_build(forest, ldescriptors.size(), ldescriptors.data());

/* Searcher object */
VlKDForestSearcher* searcher = vl_kdforest_new_searcher(forest);
VlKDForestNeighbor neighbours[2];

/* Query the first ten points for now */
for(int i=0; i < 10; i++){
    int nvisited = vl_kdforestsearcher_query(searcher, &neighbours, 2, rdescriptors[i].data());

    cout << nvisited << neighbours[0].distance << neighbours[1].distance;

}

私が知る限り、それはうまくいくはずですが、私が得たのは、距離についてはnanです。記述子配列の長さはチェックアウトされるため、ツリーにデータが入っているように見えます。キーポイントをプロットしましたが、それらも妥当に見えるため、データはかなり正常です。

私は何が欠けていますか?

こちらのかなりまばらなドキュメント (API へのリンク): http://www.vlfeat.org/api/kdtree.html

4

1 に答える 1

1

私は何が欠けていますか?

の 2 番目の引数は、次vl_kdforestsearcher_queryへのポインタを取りますVlKDForestNeighbor

vl_size
vl_kdforestsearcher_query(
  VlKDForestSearcher *self,
  VlKDForestNeighbor *neighbors,
  vl_size numNeighbors,
  void const *query
);

しかし、ここで宣言してから、正しくない 2 番目のパラメーターとしてVlKDForestNeighbor neighbours[2];渡しました。コンパイラーが警告を発行した可能性があります。&neighboursincompatible pointer types

配列を宣言したので、代わりに行う必要があるのは、最初の隣人へのポインターを明示的に渡すことです。

int nvisited = vl_kdforestsearcher_query(searcher, &neighbours[0], 2, qrys[i]);

または、代わりにコンパイラーに任せてください:

int nvisited = vl_kdforestsearcher_query(searcher, neighbours, 2, qrys[i]);

編集

で kd-tree を構築する方法に関連する 2 番目の (主要な) 問題が実際にありますldescriptors.data()

ここではstd::vector<float>*、VLFeatfloat *がすべてのデータ ポイントを行優先順で含む連続した配列を期待している場合にポインターを渡します。したがって、できることは、次の形式でデータをコピーすることです。

float *data = new float[128*ldescriptors.size()];

for (unsigned int i = 0; i < ldescriptors.size(); i++)
  std::copy(ldescriptors[i].begin(), ldescriptors[i].end(), data + 128*i);

vl_kdforest_build(forest, ldescriptors.size(), data);

// ...

// then, right after `vl_kdforest_delete(forest);`
// do a `delete[] data;`
于 2015-02-21T18:12:44.017 に答える