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

Bug of "meanValue" function #63

Open
Study-is-happy opened this issue Jul 22, 2020 · 1 comment
Open

Bug of "meanValue" function #63

Study-is-happy opened this issue Jul 22, 2020 · 1 comment

Comments

@Study-is-happy
Copy link

Study-is-happy commented Jul 22, 2020

In "meanValue" function, if "mean" is assigned with a new value, one of the descriptor would change to this new value too.
I don't know if it is what it should be, but I think the descriptor in this function should not be modified. Here is what I am guessing: when initializing the cluster, a random descriptor is chosen as the "mean", but not in a "clone" way. So if the mean is changing, that chosen descriptor would be changing at the same time (they are the referencing the same address)

@bcrobo
Copy link

bcrobo commented Jan 31, 2022

Hey @Study-is-happy,

I'm not maintainer of this repository but still... I was intrigued by your suspicions.
A bit of overview on FORB, FBrief and FSurf64 data types shows that they have respectively the following types:

FORB::TDescriptor -> cv::Mat
FORB::pDescriptor -> cv::Mat*

FBrief::TDescriptor -> std::bitset<L> // with L = 256
FBrief::pDescriptor -> std::bitset<L>*

FSurf64::TDescriptor -> std::vector<float>
FSurf64::pDescriptor -> std::vector<float>*

The method getFeatures of TemplatedVocabulary is building the vector of descriptors by taking the address of each plain type and push everything into a std::vector<pDescriptor>.

Later on, in HKmeansStep method, the clusters are declared as vector of plain types here and the F::meanValue(cluster_descriptors, clusters[c]); is called. But note that at this time:

clusters[c] -> cv::Mat // FORB
clusters[c] -> std::bitset<L> // FBrief
clusters[c] -> std::vector<float> // FSurb64

Lets have a look at each descriptor meanValue function.
For FORB the line where you can have a doubt is probably:

mean = cv::Mat::zeros(1, FORB::L, CV_8U);

unfortunately you are right, mean points to a descriptor memory chunk. Since, it has the same size than the cv::Mat::zeros() it sets the memory chunk to zero and computes the mean value in-place (inside the descriptors population...).

For FBrief and FSurf64, the clusters[c] are plain std types. So it modifies the element of the clusters vector passed by reference (and has nothing to do with the input descriptors because the vector of clusters contains values (i.e. TDescriptor)).
Note the descriptor in memory is still valid and is held by a cv::Mat header stored in the training_features you pass to create the vocabulary. In the end, I think the code should be fixed and harmonized to perform a copy at the cluster creation time (as it is done for FBrief and FSurf).

I agree this is not as readable as it should be, especially for the cv::Mat case.

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

2 participants