Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

BOWKMeansTrainer and features extraction

After some months, I start again to do some optimization with my code, but I forgot somethink, I think.

I need to perform Bag of Words to clusterize features extracted from images. Let's see some code.

Extract features and put them into a vector.

cv::Mat featuresVector;
for (int i = 0; i < numberImages; ++i) // <- first features extraction
{
    cv::Mat featuresExtracted = runExtractFeature(face, featuresExtractionAlgorithm);
    featuresVector.push_back(featuresExtracted);
}

Them, I want to clusterize them with BOWKMeansTrainer.

cv::BOWKMeansTrainer bowTrainer(dictionarySize, termCriteria, retries, centersFlags);
bowTrainer.add(featuresVector);
cv::Mat dictionary = bowTrainer.cluster();

Then, preare for bag of words in this way

cv::Ptr<cv::DescriptorMatcher> matcher = cv::FlannBasedMatcher::create();
cv::Ptr<cv::DescriptorExtractor> extractor = cv::xfeatures2d::SiftDescriptorExtractor::create(); // <-
cv::BOWImgDescriptorExtractor bowDE(extractor, matcher);
bowDE.setVocabulary(dictionary);

Now I can start bag of words

for (int i = 0; i < numberImages; ++i)
{
    cv::Mat face = faceMatVector[i]; // <- contains image read with imread.
    std::vector<cv::KeyPoint> keypoints;
    detector->detect(face, keypoints); <- // second one features extraction
    cv::Mat bowDescriptors;
    bowDE.compute(face, keypoints, bowDescriptors);
}

As you can see, in this way, I perform features extraction from image two time: first one with the first loop, and the second one with the last loop (see comments on code), because I need descriptors to clusterize with BOWKMeansTrainer, but I need keypoints to calculate bowDescriptors with BOWImgDescriptorExtractor (matching and so on).

My question is: Is this necessary or can I avoid that? I failed something? Can I take from keypoints from somewhere in the last loop without re-detect them? Can I just save keypoints detected in the first loop and then re-use them in the last loop to computer BOWImgDescriptorExtractor?

Thanks for your answer.