Cannot make EmguCV-OpenCV BOW Categorization work properly

asked 2017-01-19 05:45:28 -0500

Koray gravatar image

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)
edit retag flag offensive close merge delete

Comments

1

while we can help you with general opencv problems,

those specific to emgu, or similar, unsupported 3rd party apis are quite off-topic here.

try e.g. on www.emgu.com/forum/

berak gravatar imageberak ( 2017-01-19 06:01:21 -0500 )edit

also, when traversing directories and loading images, please check, if that succeeded at all.

there mightbe non-images, like a readme.txt or an (invisible) thumbs.db there, leading to invalid Mat's, empty keypoint arrays, and access errors .

berak gravatar imageberak ( 2017-01-19 06:19:33 -0500 )edit

Thanks for respose. I have already send my question to that forum. I wish someone show me what I am doing wrong. I am sure that all train, template and test images are OK. And they are loaded without any problems. I have tried with many different images, many different things. As I have mentioned, the AccessViolation error occurs sometimes on the classification stage. It is sometimes sucessful with many large amout and size of images, but sometimes not. SVM class behavior difference when loaded from file is also very anoying. Thanks again.

Koray gravatar imageKoray ( 2017-01-19 06:38:21 -0500 )edit