我正在尝试使用SVM进行3级分类。为此,我在SVM培训期间准备词汇。但由于我在SVM预测期间得到随机结果,所以我怀疑我的词汇创建方法存在一些问题。我创建词汇的代码如下:
//Mat train --- it should contain the feature vectors
//Mat response-- it will contain the class labels
void svm::createTrainingDateUsingBOW(int flag,Mat& train, Mat& response, int label)
{
int cluster = 9; // Common for all classes
cv::Mat imageForTraining;
std::vector<cv::KeyPoint> keypoints;
cv::SurfFeatureDetector detector(500);
cv::Ptr<cv::DescriptorExtractor> cvDescExt = new cv::SurfDescriptorExtractor();
cv::Mat descriptors;
cv::BOWKMeansTrainer bow(cluster, cv::TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, FLT_EPSILON), 1, cv::KMEANS_PP_CENTERS);
cv::Mat vocabulary;
if (flag == 1)
{
for(int i=1; i<=400; i++)
{
counter++;
cout<<"\n counter: "<<counter;
char filepath[255];
sprintf(filepath, "class1/%d.JPG",i); // we need class1/1.JPG etc
imageForTraining = cv::imread(filepath, CV_LOAD_IMAGE_GRAYSCALE);
// Preparing keypoints using detector
detector.detect(imageForTraining, keypoints);
// now getting the DESCRIPTORS for the given keypoints
cvDescExt->compute(imageForTraining, keypoints, descriptors);
//BOW
if(keypoints.size() > cluster) // so that (N<k) error won't come
{
if (!descriptors.empty()) bow.add(descriptors);
//VOCABULARY
vocabulary = bow.cluster();
cv::Ptr<DescriptorExtractor> extractor = new SurfDescriptorExtractor();
cv::Ptr<DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased");
cv::BOWImgDescriptorExtractor descExtractor (extractor, matcher);
descExtractor.setVocabulary(vocabulary);
Mat bowDescriptors;
descExtractor.compute(imageForTraining, keypoints, bowDescriptors);
if ( !bowDescriptors.empty())
{
train.push_back(bowDescriptors);
response.push_back(label);
}
}// ending if loop
} // ending For loop
}// ending if(flag ) loop
if (flag == 2)
{
for(int i=1; i<=400; i++)
{
counter++;
cout<<"\n counter: "<<counter;
char filepath[255];
sprintf(filepath, "class2/%d.JPG",i); // we need class1/1.JPG etc
imageForTraining = cv::imread(filepath, CV_LOAD_IMAGE_GRAYSCALE);
// Preparing keypoints using detector
detector.detect(imageForTraining, keypoints);
// now getting the DESCRIPTORS for the given keypoints
cvDescExt->compute(imageForTraining, keypoints, descriptors);
//BOW
if(keypoints.size() > cluster) // so that (N<k) error won't come
{
if (!descriptors.empty()) bow.add(descriptors);
//VOCABULARY
vocabulary = bow.cluster();
cv::Ptr<DescriptorExtractor> extractor = new SurfDescriptorExtractor();
cv::Ptr<DescriptorMatcher> matcher = cv::DescriptorMatcher::create("FlannBased");
cv::BOWImgDescriptorExtractor descExtractor (extractor, matcher);
descExtractor.setVocabulary(vocabulary);
Mat bowDescriptors;
descExtractor.compute(imageForTraining, keypoints, bowDescriptors);
if ( !bowDescriptors.empty())
{
train.push_back(bowDescriptors);
response.push_back(label);
}
}// ending if loop
} // ending For loop
}// ending if(flag ) loop
....Similary for Class-3
}
答案 0 :(得分:0)
你应该包含字典中的所有词汇。 这意味着你应该一次循环所有的图片。然后,每个类别都要进行处理
答案 1 :(得分:0)
这样的代码......
struct timeval start,end;//compute time of the during
gettimeofday(&start,NULL);//get the time when program start
//inital stack
initModule_nonfree();
initModule_features2d();
initModule_contrib();
//build dicationary
int wordCount = 10000;//num of vocabulary in dictionary
//string trainDataPath = "/home/win/winshare/datasets/4categories";//test datasets
string trainDataPath = "/workspace/datasets/mirflickr";//final using datsets
//change string to const char *
const char* c_trainDataPath = trainDataPath.c_str();
struct dirent* ent = NULL;
DIR *pDir;
//readdir return following dirent
//struct dirent {
// ino_t d_ino; /* inode number */
// off_t d_off; /* not an offset; see NOTES */
// unsigned short d_reclen; /* length of this record */
// unsigned char d_type; /* type of file; not supported
// by all filesystem types */
// char d_name[256]; /* filename */
//};
pDir = opendir(c_trainDataPath);
if (pDir == NULL){
cout << "can not open dir ,maybe it's a file" << endl;
return -1;
}
Mat allDescriptors;//store all descriptors
Ptr<FeatureDetector> detector = FeatureDetector::create("SURF");
Ptr<DescriptorExtractor> extractor = DescriptorExtractor::create("SURF");
while ((ent = readdir(pDir)) != NULL){
if (ent->d_type == 8)// 8 is a file 4 is a dir
{
//cout << ent->d_name << endl;
string current_file = trainDataPath + "/" + ent->d_name;
cout << "processing" + current_file << endl;
Mat image = imread(current_file);
if (!image.empty()){//pass non picture file
vector<KeyPoint> keyPoints;
Mat descriptors;
//compute keypoint in this picture
detector->detect(image, keyPoints);
//compute descriptors in this pircture
extractor->compute(image, keyPoints, descriptors);
if (allDescriptors.empty()){
allDescriptors.create(0, descriptors.cols, descriptors.type());
}
allDescriptors.push_back(descriptors);//collect all descriptor in allDescriptors
}
}
}
assert(!allDescriptors.empty()); //assert allDescriptors
cout << "building vocabulary ..." << endl;
BOWKMeansTrainer bowTrianer(wordCount);
Mat vocabulary = bowTrianer.cluster(allDescriptors);
cout << "done build vocabulary " << endl;
//done build dictionary
string result = trainDataPath + "/" + "result";
const char* c_result = result.c_str();
//create a drectory to store dictionary we build
mkdir(c_result, 0666);
string vocabularyFile = result + "/" + "vocabulary";
FileStorage fs(vocabularyFile, FileStorage::WRITE);
if (fs.isOpened()){
fs << "vocabulary" << vocabulary;
}