DLoopDetector icon indicating copy to clipboard operation
DLoopDetector copied to clipboard

Problem with training new vectors for FAST features.

Open thesidjway opened this issue 7 years ago • 4 comments

Hello @dorian3d, First of all thank you for this great library. I modified the demo.cpp in DBoW2 that works on Orb to train feature vectors in order to generate a vocabulary similar to the one used in DLoopDetector.

Here are the two functions I'm using:

void loadFeatures(vector<vector<BRIEF::bitset > > &features)
{
  features.clear();
  features.reserve(NIMAGES);

  cout << "Extracting BRIEF features..." << endl;
  for(int i = 1; i < 25; ++i)
  {
    stringstream ss;
    ss << "/home/thesidjway/train2/DBoW2/build/brief_train/frame" <<  setfill('0') << setw(4) << i << ".jpg";
    cout << ss.str() << endl;
    cv::Mat image = cv::imread(ss.str(), 0);
    cv::Mat mask;
    vector<cv::KeyPoint> keypoints, kpt;
    cv::Mat descriptors;
    vector<BRIEF::bitset> descriptors_1;
    DVision::BRIEF m_brief;
    cv::FAST(image, kpt, 20, true);
    m_brief.compute(image, kpt, descriptors_1);
    features.push_back(descriptors_1);
  }
}
void testVocCreation(const vector<vector<BRIEF::bitset > > &features)
{
  // branching factor and depth levels 
  const int k = 10;
  const int L = 6;
  const WeightingType weight = TF_IDF;
  const ScoringType score = L1_NORM;

  BriefVocabulary voc(k, L, weight, score);

  cout << "Creating a small " << k << "^" << L << " vocabulary..." << endl;
  voc.create(features);
  cout << "... done!" << endl;


  cout << "Vocabulary information: " << endl
  << voc << endl << endl;
  
  // save the vocabulary to disk
  cout << endl << "Saving vocabulary..." << endl;
  voc.save("/home/thesidjway/brief_k10L6_edited.voc.gz");
  cout << "Done" << endl;
}

The functions compile and run just fine and I am able to output a voc.gz file but when I import the file into the DLoopDetector, it just crashes.

Could you please help me in this regard? Also can existing vocabularies be appended with new BoWvectors in any way?

thesidjway avatar Jul 22 '17 07:07 thesidjway

@dorian3d Did you take a look?

thesidjway avatar Jul 24 '17 17:07 thesidjway

Hi @thesidjway.

I tried your code and runs fine. How do you load the vocabulary into the DLoopDetector? This works fine for me:

BriefVocabulary voc(VOC_FILENAME);
BriefLoopDetector detector(voc);

This library implements static vocabularies only, so new BowVector entries can't be appended to them. The vocabulary has to be done from scratch to add new data.

dorian3d avatar Jul 25 '17 19:07 dorian3d

Hi, I had a related doubt. If i wanted to train my vocab for surf64 features, then would modifying the loadfeatures() method here for surf64, be the same thing as letting function 'run' in demodetector.h extract surf descriptors for the images i want ( code doing the extraction: extractor(im,keys,descriptors); ), and commenting out the loop detection part instead adding the descriptors to a vector which i would analogously call 'features' (as in here), and pass to testvoccreation function? I ask because I implemented it that way, but the saved vocab when substituted, doesn't detect any loop closures for me, as opposed to the few loop closures i was getting from using a pretrained vocab i had been using before.

PS:The library is very useful, Thanks!

gunshi avatar Aug 11 '17 12:08 gunshi

Also I'm unsure of how to replace: m_brief.compute(image, kpt, descriptors_1); from above code example.

Since if we look at the following lines from Surfset.h in DVision library:

namespace DVision {

class Matches;

/// Collection of surf keypoints + descriptors

class SurfSet 

{

public:

  /// KeyPoint collection

	std::vector<cv::KeyPoint> keys;

	/// Descriptors associated to the keypoints

	std::vector<float> descriptors;

	/// Laplacian signs of the keypoints

	std::vector<int> laplacians;

The compute function defined later seems to be storing the descriptors in flattened 1D vector form, the class member 'desciptors', and does not take our own descriptors variable as parameter to store it in that, unlike brief. So then I should call compute, then access member "descriptors", reshape it to 2D, then assign it to vector<vectorFSURF::TDesriptor> that i want(called 'features' in the example) and send that to testVocCreation?

gunshi avatar Aug 11 '17 14:08 gunshi