Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail to load binary orbvoc files on windows. #5

Open
gpdaniels opened this issue Jan 24, 2017 · 9 comments
Open

Fail to load binary orbvoc files on windows. #5

gpdaniels opened this issue Jan 24, 2017 · 9 comments

Comments

@gpdaniels
Copy link

In "Vocabulary.cpp" line 1053:
std::ifstream ifile(filename);
may work on linux but you need to set that the data is binary ensure the data is not modified.
It needs to be replaced with:
std::ifstream ifile(filename, std::ios::binary);

Similarly on line 1036 replace with:
std::ofstream file_out(filename, std::ios::binary);

@yang3kui
Copy link

Totally agree with @gpdaniels .

I read the txt vocabulary file in orb_slam2 and then save it to binary format using Vocabulary::save.

When i tried to load the binary vocabulary file, i met a crash.

After read this, i added std::ios::binary in "Vocabulary.cpp" line 1053 and 1036.

Now, it works great.

@odiseo123
Copy link

odiseo123 commented Feb 21, 2017

Hi @yang3kui,
Could you confirm that the vocabulary created using...
voc.save(tempPath.string() + ".txt");
... can be read with ORB_SLAM2?

@yang3kui
Copy link

@odiseo123

I don't think Vocabulary::save can save a file in plain txt format, as we can see here
https://github.com/yang3kui/DBow3/blob/master/src/Vocabulary.cpp#L1032

The suffix ".txt" is ignored and the vocabulary is saved in YAML format. However, DBOW2 can read YAML format data, using TemplatedVocabulary<TDescriptor,F>::load
https://github.com/dorian3d/DBoW2/blob/master/include/DBoW2/TemplatedVocabulary.h#L1436

So, i think the vocabulary created using voc.save(tempPath.string() + ".txt") can be read with ORB_SLAM2, but not in plain txt format, as you indicates.

And also, i think the YAML format is very slow. Saving and loading in binary format may be a wiser choise.

I have not tried this, so i cannot confirm it now. What i can confirm is that the plain txt along with orb_slam2 can be loaded correctly by DBOW3.

@yang3kui
Copy link

I am also very glad to see that this bug has already been fixed in a recent commit b4163da0c7ba30e67e54470db0c6b103bf104e7b..

I think this issue can be closed now.

@odiseo123
Copy link

odiseo123 commented Feb 23, 2017

Hi @yang3kui
I tested a DBoW3 vocabulary (binary yet saved as txt) with ORBSLAM2. As expected it does not work as the format seems not to be recognized:

Vocabulary loading failure: This is not a correct text file!
Wrong path to vocabulary.

@yang3kui
Copy link

@odiseo123
as i said, use

virtual void load(const cv::FileStorage &fs, const std::string &name = "vocabulary");

instead of

void load_fromtxt(const std::string &filename);

currently, dbow3 ignores the suffix ".txt" and save vocabulary using cv::filestorage.

@odiseo123
Copy link

Hi @yang3kui,
Thanks for the reply. Maybe just to make it clearer for me:
-My approach is to generate a DBoW2-like text file using DBoW3, that is: human readable, non-yaml, *.txt extension. In such a way I should be able to run ORBSLAM2 without modifying its code. Thanks to your comments I realized this could not be done using the default (DBoW3)Vocabulary::save function, as this function only allows saving in binary and YML. Ultimately one has to implement a saveToTextFile() function which is pretty much the same as found in DBoW2.
I have tried this and can confirm that it works.
-Your suggested approach is to generate a binary DBoW3 vocabulary(binary, non *.txt extension) but then modify ORBSLAM2 System.ccp file:

    mpVocabulary = new ORBVocabulary();
    bool bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);

Could you please let me know if this is what you meant? I would prefer a solution like yours rather than my "faking DBoW2" approach.

@yang3kui
Copy link

@odiseo123

It is glad to see the txt format works.

ORBSLAM2 do not support binary format by default. Therefore,

bool bVocLoad = mpVocabulary->loadFromTextFile(strVocFile);

will not work for binary format.

Technically, you have to write a mpVocabulary::loadFromBinaryFile youself. I think this patch, which provides a saveToBinaryFile and a loadFromBinaryFile, is a good start point.

I have not tried this, but i think the fastest way to make the binary format works is like this

  • copy saveToBinaryFile to DBOW3 to save the binary vocabulary.
  • copy loadFromBinaryFile to ORB_SLAM2 to load the binary vocabulary.

@rocinant
Copy link

Hi guys, I just want to report that even after adding this patch of loadFromBinaryFile function to original ORB_SLAM2, I still couldn't successfully read the vocabulary created via DBoW3 save function, no matter it is in which format suffix (yml.gz, txt.tar.gz, plain .txt suffix, .dbow3). According to your discussion, no matter which suffix I wrote, the DBoW3 would output binary format file, so I thought with the added patch's function to read in the binary file, the ORB_SLAM2 should be able to work with vocabulary created via DBoW3. But when I ran the code, it crashes every try. By the way, my DBoW3 is built and running on Windows 7 64 bits via VC15 win32 release build, and generated vocabulary is read into ORB_SLAM2 running on an Android platform. Any hint will be appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants