BOW Kmeans trainer problem
Hello,
i`m using BOWKmeansTrainer to categorize images in my project. Everything works fine, when BOW trainer runs only once. But, when i was trying to find optimal number of descriptors per image class in categorization, I have discovered some strange behaviour with BOW trainer. In an example code, there is a simple program, which calculate descriptors from images (stored in directory "test") and then calculate vocabulary using BOWKmeansTrainer. I used two BOW trainers, "bowtrainer" and "bowtrainer1" with the same input descriptors and parameters. But, when I looked into saved results, I have found two different vocabularies.
Can anyone help me? What am I doing wrong ? I`m using Opencv 2.4.8 (also tested on 2.4.5)
Here is an example:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/video/background_segm.hpp"
#include "opencv2/video/tracking.hpp"
#include "opencv2/ml/ml.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
using namespace cv;
using namespace std;
int main()
{
int m_debug = 1;
initModule_nonfree();
Ptr<FeatureDetector> detector;
Ptr<FeatureDetector> control_detector;
Ptr<DescriptorExtractor> extractor;
Ptr<DescriptorMatcher> matcher;
Ptr<BOWImgDescriptorExtractor> bow_ext;
detector = FeatureDetector::create("SURF");
extractor = DescriptorExtractor::create("SURF");
matcher = DescriptorMatcher::create("BruteForce");
string path_to_images = "test";
string filepath;
Mat desc;
Mat voc,img,voc1;
vector<KeyPoint> kp;
DIR *dp;
struct dirent *dirp;
struct stat filestat;
FileStorage fs;
int dictionarySize = 1000;
TermCriteria tc(CV_TERMCRIT_ITER, 10, 0.001);
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowtrainer(1000,tc, retries, flags);
BOWKMeansTrainer bowtrainer1(1000,tc, retries, flags);
dp=opendir(path_to_images.c_str());
while((dirp = readdir(dp))){
filepath = path_to_images+"/"+dirp->d_name;
if (stat( filepath.c_str(), &filestat )) continue;
if (S_ISDIR( filestat.st_mode )) continue;
img=imread(filepath);
if(img.empty()){
continue;
}
if(m_debug){
cout<<filepath<<endl;
}
detector->detect(img, kp);
extractor->compute(img, kp, desc);
bowtrainer.add(desc);
bowtrainer1.add(desc);
}
closedir(dp);
cout << "Calculating vocabulary for "<<bowtrainer.descripotorsCount()<<" descriptors "<<endl;
voc = bowtrainer.cluster();
cout<<"Saving vocabulary ..."<<endl;
fs.open("voc.yml", FileStorage::WRITE);
fs<<"voc"<<voc;
fs.release();
cout << endl;
cout << "Calculating vocabulary for "<<bowtrainer.descripotorsCount()<<" descriptors "<<endl;
voc1 = bowtrainer1.cluster();
cout<<"Saving vocabulary ..."<<endl;
fs.open("voc1.yml", FileStorage::WRITE);
fs<<"voc1"<<voc1;
fs.release();
cout << endl;
return 0;
}