I have already asked here, but no one answered: http: //stackoverflow.com/questions/41724448/cannot-make-emgucv-opencv-bow-categorization-work-properly
I am trying to learn BOW object categorization. I have tried to implement the example given in the book "Practical OpenCV, Samarth Brahmbhatt" Chapter 8 (page 148)
- When I save the SVM's to file on the training stage and read them on the categorization stage, the result is comletely different. (If the line svm = notFromFile[category]; is removed, the results are wrong; if not, it is successful with the dataset provided by the book.)
- When I try this code with some larger datasets, I sometimes get this exception: System.AccessViolationException' in Emgu.CV.World.dll for the line bowDescriptorExtractor.Compute(frame_g, kp, img); and the application closes. It cannot be handled.
I have tried many things but could not figure them out. Any suggestions why these are happening, and how to solve, is very appreciated.
I am using emgucv-windesktop 3.1.0.2504
My implementation:
internal class Categorizer3 : ICategorizer
{
public string Name
{
get
{
return "Categorizer3";
}
}
public bool Train()
{
try
{
initDir();
Feature2D descriptorExtractor;
Feature2D featureDetector;
List<Mat> templates;
BOWKMeansTrainer bowtrainer;
BOWImgDescriptorExtractor bowDescriptorExtractor;
init(out descriptorExtractor, out featureDetector, out templates, out bowtrainer, out bowDescriptorExtractor);
List<Tuple<string, Mat>> train_set;
List<string> category_names;
make_train_set(out train_set, out category_names);
Mat vocab;
build_vocab(descriptorExtractor, featureDetector, templates, bowtrainer, out vocab);
bowDescriptorExtractor.SetVocabulary(vocab);
Dictionary<string, Mat> positive_data;
Dictionary<string, Mat> negative_data;
make_pos_neg(train_set, bowDescriptorExtractor, featureDetector, category_names, out positive_data, out negative_data);
this.train_classifiers(category_names, positive_data, negative_data);
return true;
}
catch (Exception)
{
return false;
}
}
public event TrainedEventHandler Trained;
protected void OnTrained(string fn)
{
if (this.Trained != null)
this.Trained(fn);
}
public Categorizer3()
{
}
private Feature2D create_FeatureDetector()
{
return new SURF(500);
//return new KAZE();
//return new SIFT();
//return new Freak();
}
private BOWImgDescriptorExtractor create_bowDescriptorExtractor(Feature2D descriptorExtractor)
{
LinearIndexParams ip = new LinearIndexParams();
SearchParams sp = new SearchParams();
var descriptorMatcher = new FlannBasedMatcher(ip, sp);
return new BOWImgDescriptorExtractor(descriptorExtractor, descriptorMatcher);
}
private void init(out Feature2D descriptorExtractor, out Feature2D featureDetector, out List<Mat> templates, out BOWKMeansTrainer bowtrainer, out BOWImgDescriptorExtractor bowDescriptorExtractor)
{
int clusters = 1000;
featureDetector = create_FeatureDetector();
MCvTermCriteria term = new MCvTermCriteria(10000, 0.0001d);
term.Type = TermCritType.Iter | TermCritType.Eps;
bowtrainer = new BOWKMeansTrainer(clusters, term, 5, Emgu.CV.CvEnum.KMeansInitType.PPCenters);//****
BFMatcher matcher = new BFMatcher(DistanceType.L1);//****
descriptorExtractor = featureDetector;//******
bowDescriptorExtractor = create_bowDescriptorExtractor(descriptorExtractor);
templates = new List<Mat>();
string TEMPLATE_FOLDER = "C:\\Emgu\\book\\practical-opencv\\code\\src\\chapter8\\code8-5\\data\\templates";
//string TEMPLATE_FOLDER = "C:\\Emgu\\book\\practical-opencv\\code\\src\\chapter8\\code8-5\\data\\train_images";
foreach (var filename in Directory.GetFiles(TEMPLATE_FOLDER, "*", SearchOption.AllDirectories))
{
templates.Add(GetMat(filename, true));
this.OnTrained(filename);
}
}
void make_train_set(out List<Tuple<string, Mat>> train_set, out List<string> category_names)
{
string TRAIN_FOLDER = "C:\\Emgu\\book\\practical-opencv\\code\\src\\chapter8\\code8-5\\data\\train_images";
category_names = new List<string>();
train_set = new List<Tuple<string, Mat>>();
foreach (var dir in Directory.GetDirectories(TRAIN_FOLDER))
{
// Get category name from name of the folder
string category = new DirectoryInfo(dir).Name;
category_names.Add(category);
foreach (var filename in Directory.GetFiles(dir))
{
train_set.Add(new Tuple<string, Mat>(category, GetMat(filename, true)));
this.OnTrained(filename);
}
}
}
void build_vocab(Feature2D descriptorExtractor, Feature2D featureDetector, List<Mat> templates ...
(more)