Beispiel #1
0
        private IBagOfWords <Bitmap> CreateBow()
        {
            var binarySplit = new BinarySplit(10);
            var surfBow     = BagOfVisualWords.Create(10);

            return(surfBow.Learn(Images.ToArray()));
        }
Beispiel #2
0
        private static void CreateBoW()
        {
            var numberOfWords = 36;

            foreach (var file in Directory.EnumerateFiles(@"C:\Temp\TLLCamerasTestData\37_Training", "*.jpg"))
            {
                var trainingImage = (Bitmap)Bitmap.FromFile(file);

                trainingImages.Add(file, trainingImage);
            }

            foreach (var file in Directory.EnumerateFiles(@"C:\Temp\TLLCamerasTestData\37_Testing", "*.jpg"))
            {
                var testImage = (Bitmap)Bitmap.FromFile(file);

                testingImages.Add(file, testImage);
            }



            // We will use SURF, so we can use a standard clustering
            // algorithm that is based on Euclidean distances. A good
            // algorithm for clustering codewords is the Binary Split
            // variant of the K-Means algorithm.

            // Create a Binary-Split clustering algorithm
            BinarySplit binarySplit = new BinarySplit(numberOfWords);

            // Create bag-of-words (BoW) with the given algorithm
            BagOfVisualWords surfBow = new BagOfVisualWords(binarySplit);

            // Compute the BoW codebook using training images only
            IBagOfWords <Bitmap> bow = surfBow.Learn(trainingImages.Values.ToArray());

            // now that we've created the bow we need to use it to create a representation of each training and test image

            foreach (var trainingImage in trainingImages.Keys)
            {
                var asBitmap = trainingImages[trainingImage] as Bitmap;

                var featureVector = (bow as ITransform <Bitmap, double[]>).Transform(asBitmap);

                var featureString = featureVector.ToString(DefaultArrayFormatProvider.InvariantCulture);

                trainingFeatures.Add(trainingImage, featureVector);
            }

            foreach (var testingImage in testingImages.Keys)
            {
                var asBitmap = testingImages[testingImage] as Bitmap;

                var featureVector = (bow as ITransform <Bitmap, double[]>).Transform(asBitmap);

                var featureString = featureVector.ToString(DefaultArrayFormatProvider.InvariantCulture);

                testingFeatures.Add(testingImage, featureVector);
            }
        }
Beispiel #3
0
 public void BinarySplitConstructorTest3()
 {
     // Create a new algorithm
     BinarySplit binarySplit = new BinarySplit(3);
     Assert.IsNotNull(binarySplit.Clusters);
     Assert.IsNotNull(binarySplit.Distance);
     Assert.IsNotNull(binarySplit.Clusters.Centroids);
     Assert.IsNotNull(binarySplit.Clusters.Count);
     Assert.IsNotNull(binarySplit.Clusters.Covariances);
     Assert.IsNotNull(binarySplit.Clusters.Proportions);
 }
Beispiel #4
0
        public void BinarySplitConstructorTest()
        {
            Accord.Math.Random.Generator.Seed = 0;


            // Declare some observations
            double[][] observations = 
            {
                new double[] { -5, -2, -1 },
                new double[] { -5, -5, -6 },
                new double[] {  2,  1,  1 },
                new double[] {  1,  1,  2 },
                new double[] {  1,  2,  2 },
                new double[] {  3,  1,  2 },
                new double[] { 11,  5,  4 },
                new double[] { 15,  5,  6 },
                new double[] { 10,  5,  6 },
            };

            double[][] orig = observations.MemberwiseClone();

            // Create a new binary split with 3 clusters 
            BinarySplit binarySplit = new BinarySplit(3);

            // Compute the algorithm, retrieving an integer array
            //  containing the labels for each of the observations
            int[] labels = binarySplit.Compute(observations);

            // As a result, the first two observations should belong to the
            //  same cluster (thus having the same label). The same should
            //  happen to the next four observations and to the last three.

            Assert.AreEqual(labels[0], labels[1]);

            Assert.AreEqual(labels[2], labels[3]);
            Assert.AreEqual(labels[2], labels[4]);
            Assert.AreEqual(labels[2], labels[5]);

            Assert.AreEqual(labels[6], labels[7]);
            Assert.AreEqual(labels[6], labels[8]);

            Assert.AreNotEqual(labels[0], labels[2]);
            Assert.AreNotEqual(labels[2], labels[6]);
            Assert.AreNotEqual(labels[0], labels[6]);


            int[] labels2 = binarySplit.Clusters.Nearest(observations);

            Assert.IsTrue(labels.IsEqual(labels2));

            // the data must not have changed!
            Assert.IsTrue(orig.IsEqual(observations));
        }
Beispiel #5
0
        /// <summary>
        ///   This methods computes the Bag-of-Visual-Words with the training images.
        /// </summary>
        ///
        private void btnBagOfWords_Click(object sender, EventArgs e)
        {
            int numberOfWords = (int)numWords.Value;

            // Create a Binary-Split clustering algorithm
            BinarySplit binarySplit = new BinarySplit(numberOfWords);

            // Create bag-of-words (BoW) with the given algorithm
            BagOfVisualWords bow = new BagOfVisualWords(binarySplit);

            if (cbExtended.Checked)
            {
                bow.Detector.ComputeDescriptors = SpeededUpRobustFeatureDescriptorType.Extended;
            }

            Stopwatch sw1 = Stopwatch.StartNew();

            // Compute the BoW codebook using training images only
            var points = bow.Compute(originalTrainImages.Values.ToArray());

            sw1.Stop();


            Stopwatch sw2 = Stopwatch.StartNew();

            // Extract features for all images
            foreach (ListViewItem item in listView1.Items)
            {
                // Get item image
                Bitmap image = originalImages[item.ImageKey] as Bitmap;

                // Process image
                double[] featureVector = bow.GetFeatureVector(image);
                string   featureString = featureVector.ToString(DefaultArrayFormatProvider.InvariantCulture);

                if (item.SubItems.Count == 2)
                {
                    item.SubItems[1].Text = featureString;
                }
                else
                {
                    item.SubItems.Add(featureString);
                }

                int classLabel = (item.Tag as Tuple <double[], int>).Item2;
                item.Tag = Tuple.Create(featureVector, classLabel);
            }

            sw2.Stop();

            lbStatus.Text = "BoW constructed in " + sw1.Elapsed + "s. Features extracted in " + sw2.Elapsed + "s.";
            btnSampleRunAnalysis.Enabled = true;
        }
Beispiel #6
0
        public void binary_split_new_method()
        {
            #region doc_sample1
            // Use a fixed seed for reproducibility
            Accord.Math.Random.Generator.Seed = 0;

            // Declare some data to be clustered
            double[][] input = 
            {
                new double[] { -5, -2, -1 },
                new double[] { -5, -5, -6 },
                new double[] {  2,  1,  1 },
                new double[] {  1,  1,  2 },
                new double[] {  1,  2,  2 },
                new double[] {  3,  1,  2 },
                new double[] { 11,  5,  4 },
                new double[] { 15,  5,  6 },
                new double[] { 10,  5,  6 },
            };

            // Create a new binary split with 3 clusters 
            BinarySplit binarySplit = new BinarySplit(3);

            // Learn a data partitioning using the Binary Split algorithm
            KMeansClusterCollection clustering = binarySplit.Learn(input);

            // Predict group labels for each point
            int[] output = clustering.Decide(input);

            // As a result, the first two observations should belong to the
            //  same cluster (thus having the same label). The same should
            //  happen to the next four observations and to the last three.
            #endregion

            Assert.AreEqual(output[0], output[1]);

            Assert.AreEqual(output[2], output[3]);
            Assert.AreEqual(output[2], output[4]);
            Assert.AreEqual(output[2], output[5]);

            Assert.AreEqual(output[6], output[7]);
            Assert.AreEqual(output[6], output[8]);

            Assert.AreNotEqual(output[0], output[2]);
            Assert.AreNotEqual(output[2], output[6]);
            Assert.AreNotEqual(output[0], output[6]);

            int[] labels2 = binarySplit.Clusters.Nearest(input);

            Assert.IsTrue(output.IsEqual(labels2));
        }
        static void ImageFeatures()
        {
            Dictionary <string, Bitmap> testImages = new Dictionary <string, Bitmap>();

            testImages.Add("img_acropolis", (Bitmap)Bitmap.FromFile("test_imgs/acropolis_athens.jpg"));
            testImages.Add("img_cathedral", (Bitmap)Bitmap.FromFile("test_imgs/amiens_cathedral.jpg"));
            testImages.Add("img_bigben", (Bitmap)Bitmap.FromFile("test_imgs/big_ben.jpg"));

            int numberOfWords = 6; // number of cluster centers: typically >>100

            // Create a Binary-Split clustering algorithm
            BinarySplit binarySplit = new BinarySplit(numberOfWords);

            IBagOfWords <Bitmap> bow;
            // Create bag-of-words ( BoW ) with the given algorithm
            BagOfVisualWords surfBow = new BagOfVisualWords(binarySplit);

            // Compute the BoW codebook using training images only
            Bitmap[] bmps = new Bitmap[testImages.Count];
            testImages.Values.CopyTo(bmps, 0);
            surfBow.Compute(bmps);
            bow = surfBow;

            // this model needs to be saved once it is calculated: only compute it once to calculate features
            // from the collection as well as for new queries.
            // THE SAME TRAINED MODEL MUST BE USED TO GET THE SAME FEATURES!!!


            Dictionary <string, double[]> testImageFeatures = new Dictionary <string, double[]>();

            // Extract features for all images
            foreach (string imagename in testImages.Keys)
            {
                double[] featureVector = bow.GetFeatureVector(testImages[imagename]);
                testImageFeatures.Add(imagename, featureVector);
                Console.Out.WriteLine(imagename + " features: " + featureVector.ToString(DefaultArrayFormatProvider.InvariantCulture));
            }

            // Calculate Image Similarities
            string[] imagenames = new string[testImageFeatures.Keys.Count];
            testImageFeatures.Keys.CopyTo(imagenames, 0);

            for (int i = 0; i < imagenames.Length; i++)
            {
                for (int j = i + 1; j < imagenames.Length; j++)
                {
                    double dist = Distance.Cosine(testImageFeatures[imagenames[i]], testImageFeatures[imagenames[j]]);
                    Console.Out.WriteLine(imagenames[i] + " <-> " + imagenames[j] + " distance: " + dist.ToString());
                }
            }
        }
Beispiel #8
0
        public void LargeTest()
        {
            // Requires data from the National Data Science bowl
            // https://github.com/accord-net/framework/issues/58

            var trainingDirectory = @"C:\Users\CésarRoberto\Downloads\train\train\";

            var images = LabeledImages.FromDirectory(trainingDirectory).ToArray();

            var binarySplit = new BinarySplit(32);

            var bow = new BagOfVisualWords(binarySplit);

            bow.Compute(images.Select(i => i.Item).Take(50).ToArray());
        }
Beispiel #9
0
        private void setBinaryCluster(System.IO.StreamReader sr)
        {
            BinarySplit             bSplit     = new BinarySplit(k);
            KMeansClusterCollection kmeansColl = bSplit.Clusters;

            for (int i = 0; i < k; i++)
            {
                double[] mns = (from s in (sr.ReadLine().Split(new char[] { ',' })) select System.Convert.ToDouble(s)).ToArray();
                sr.ReadLine();
                double        p  = System.Convert.ToDouble(sr.ReadLine());
                KMeansCluster kc = new KMeansCluster(kmeansColl, i);
                kc.Mean       = mns;
                kc.Proportion = p;
            }
            clusterCollection = kmeansColl;
            model             = bSplit;
        }
Beispiel #10
0
        private static void binarySplit(double[][] inputs)
        {
            // Create a binary-split algorithm
            var binarySplit = new BinarySplit(k: 3)
            {
                Distance      = new SquareEuclidean(),
                MaxIterations = 1000
            };

            // Use it to learn a data model
            var model = binarySplit.Learn(inputs);

            // Use the model to group new instances
            int[] prediction = model.Decide(inputs);

            // Plot the results
            ScatterplotBox.Show("Binary Split's answer", inputs, prediction).Hold();
        }
Beispiel #11
0
        public void buildModel()
        {
            if (inputMatrix == null)
            {
                getMatrix();
            }
            switch (cType)
            {
            case clusterType.KMEANS:
                KMeans kmeans = new KMeans(k);
                kmeans.Compute(inputMatrix, precision);
                clusterCollection = kmeans.Clusters;
                model             = kmeans;
                break;

            case clusterType.BINARY:
                BinarySplit bSplit = new BinarySplit(k);
                bSplit.Compute(inputMatrix, precision);
                clusterCollection = bSplit.Clusters;
                model             = bSplit;
                //Console.WriteLine("BinarySplit");
                break;

            case clusterType.GAUSSIANMIXTURE:
                GaussianMixtureModel gModel = new GaussianMixtureModel(k);
                gModel.Compute(inputMatrix, precision);
                clusterCollection = gModel.Gaussians;
                model             = gModel;
                break;

            default:
                break;
            }

            lbl = new List <string>();
            for (int i = 0; i < k; i++)
            {
                lbl.Add(i.ToString());
            }
        }
Beispiel #12
0
        /// <summary>
        ///   This methods computes the Bag-of-Visual-Words with the training images.
        /// </summary>
        ///
        private void btnBagOfWords_Click(object sender, EventArgs e)
        {
            int numberOfWords = (int)numWords.Value;


            // Create a Binary-Split clustering algorithm
            BinarySplit binarySplit = new BinarySplit(numberOfWords);

            Stopwatch sw1 = Stopwatch.StartNew();

            IBagOfWords <Bitmap> bow;

            if (rbSurf.Checked)
            {
                // Create bag-of-words (BoW) with the given algorithm
                var surfBow = new BagOfVisualWords(binarySplit);

                // Compute the BoW codebook using training images only
                surfBow.Compute(originalTrainImages.Values.ToArray());

                bow = surfBow;
            }

            else
            {
                // Alternative creation using the FREAK detector

                // Create a Binary-Split clustering algorithm
                var kmodes   = new KModes <byte>(numberOfWords, new Hamming());
                var detector = new FastRetinaKeypointDetector();

                // Create bag-of-words (BoW) with the given algorithm
                var freakBow = new BagOfVisualWords <FastRetinaKeypoint, byte[]>(detector, kmodes);

                // Compute the BoW codebook using training images only
                freakBow.Compute(originalTrainImages.Values.ToArray());

                bow = freakBow;
            }

            sw1.Stop();

            Stopwatch sw2 = Stopwatch.StartNew();

            // Extract features for all images
            foreach (ListViewItem item in listView1.Items)
            {
                // Get item image
                Bitmap image = originalImages[item.ImageKey] as Bitmap;

                // Process image
                double[] featureVector = bow.GetFeatureVector(image);
                string   featureString = featureVector.ToString(DefaultArrayFormatProvider.InvariantCulture);

                if (item.SubItems.Count == 2)
                {
                    item.SubItems[1].Text = featureString;
                }
                else
                {
                    item.SubItems.Add(featureString);
                }

                int classLabel = (item.Tag as Tuple <double[], int>).Item2;
                item.Tag = Tuple.Create(featureVector, classLabel);
            }

            sw2.Stop();

            lbStatus.Text = "BoW constructed in " + sw1.Elapsed + "s. Features extracted in " + sw2.Elapsed + "s.";
            btnSampleRunAnalysis.Enabled = true;
        }
Beispiel #13
0
        /// <summary>
        ///   This methods computes the Bag-of-Visual-Words with the training images.
        /// </summary>
        ///
        private void btnBagOfWords_Click(object sender, EventArgs e)
        {
            int numberOfWords = (int)numWords.Value;


            Stopwatch sw1 = Stopwatch.StartNew();

            IBagOfWords <Bitmap> bow;

            // Check if we will use SURF or FREAK as the feature detector
            if (rbSurf.Checked)
            {
                // We will use SURF, so we can use a standard clustering
                // algorithm that is based on Euclidean distances. A good
                // algorithm for clustering codewords is the Binary Split
                // variant of the K-Means algorithm.

                // Create a Binary-Split clustering algorithm
                BinarySplit binarySplit = new BinarySplit(numberOfWords);

                // Create bag-of-words (BoW) with the given algorithm
                BagOfVisualWords surfBow = new BagOfVisualWords(binarySplit);

                // Compute the BoW codebook using training images only
                bow = surfBow.Learn(originalTrainImages.Values.ToArray());
            }
            else if (rbFreak.Checked)
            {
                // We will use the FREAK detector. The features generated by FREAK
                // are represented as bytes. While it is possible to transform those
                // to standard double vectors, we will demonstrate how to use a non-
                // Euclidean distance based algorithm to generate codewords for it.

                // Note: Using Binary-Split with normalized FREAK features would
                // possibly work better than the k-modes. This is just an example.

                // Create a k-Modes clustering algorithm
                var kmodes = new KModes <byte>(numberOfWords, new Hamming());

                // Create a FREAK detector explicitly (if no detector was passed,
                // the BagOfVisualWords would be using a SURF detector by default).
                var freak = new FastRetinaKeypointDetector();

                // Create bag-of-words (BoW) with the k-modes clustering and FREAK detector
                var freakBow = new BagOfVisualWords <FastRetinaKeypoint, byte[]>(freak, kmodes);

                // Compute the BoW codebook using training images only
                bow = freakBow.Learn(originalTrainImages.Values.ToArray());
            }
            else
            {
                // We will use HOG, so we can use a standard clustering
                // algorithm that is based on Euclidean distances. A good
                // algorithm for clustering codewords is the Binary Split
                // variant of the K-Means algorithm.

                // Create a Binary-Split clustering algorithm
                BinarySplit binarySplit = new BinarySplit(numberOfWords);

                // Create a HOG detector explicitly (if no detector was passed,
                // the BagOfVisualWords would be using a SURF detector by default).
                var hog = new HistogramsOfOrientedGradients();

                // Create bag-of-words (BoW) with the given algorithm
                var hogBow = BagOfVisualWords.Create(hog, binarySplit);

                // Compute the BoW codebook using training images only
                bow = hogBow.Learn(originalTrainImages.Values.ToArray());
            }

            sw1.Stop();

            // Now that we have already created and computed the BoW model, we
            // will use it to extract representations for each of the images in
            // both training and testing sets.

            Stopwatch sw2 = Stopwatch.StartNew();

            // Extract features for all images
            foreach (ListViewItem item in listView1.Items)
            {
                // Get item image
                Bitmap image = originalImages[item.ImageKey] as Bitmap;

                // Get a feature vector representing this image
                double[] featureVector = (bow as ITransform <Bitmap, double[]>).Transform(image);

                // Represent it as a string so we can show it onscreen
                string featureString = featureVector.ToString(DefaultArrayFormatProvider.InvariantCulture);

                // Show it in the visual grid
                if (item.SubItems.Count == 2)
                {
                    item.SubItems[1].Text = featureString;
                }
                else
                {
                    item.SubItems.Add(featureString);
                }

                // Retrieve the class labels, that we had stored in the Tag
                int classLabel = (item.Tag as Tuple <double[], int>).Item2;

                // Now, use the Tag to store the feature vector too
                item.Tag = Tuple.Create(featureVector, classLabel);
            }

            sw2.Stop();

            lbStatus.Text = "BoW constructed in " + sw1.Elapsed + "s. Features extracted in " + sw2.Elapsed + "s.";
            btnSampleRunAnalysis.Enabled = true;
        }
Beispiel #14
0
        public void custom_clustering_test()
        {
            #region doc_clustering
            // Ensure results are reproducible
            Accord.Math.Random.Generator.Seed = 0;

            // The Bag-of-Visual-Words model converts images of arbitrary
            // size into fixed-length feature vectors. In this example, we
            // will be setting the codebook size to 10. This means all feature
            // vectors that will be generated will have the same length of 10.

            // By default, the BoW object will use the sparse SURF as the
            // feature extractor and K-means as the clustering algorithm.
            // In this example, we will use the Binary-Split clustering
            // algorithm instead.

            // Create a new Bag-of-Visual-Words (BoW) model
            var bow = BagOfVisualWords.Create(new BinarySplit(10));

            // Since we are using generics, we can setup properties
            // of the binary split clustering algorithm directly:
            bow.Clustering.ComputeProportions = true;
            bow.Clustering.ComputeCovariances = false;

            // Get some training images
            Bitmap[] images = GetImages();

            // Compute the model
            bow.Learn(images);

            // After this point, we will be able to translate
            // images into double[] feature vectors using
            double[][] features = bow.Transform(images);
            #endregion

            Assert.AreEqual(-1, bow.NumberOfInputs);
            Assert.AreEqual(10, bow.NumberOfOutputs);
            Assert.AreEqual(10, bow.NumberOfWords);
            Assert.AreEqual(64, bow.Clustering.Clusters.NumberOfInputs);
            Assert.AreEqual(10, bow.Clustering.Clusters.NumberOfOutputs);
            Assert.AreEqual(10, bow.Clustering.Clusters.NumberOfClasses);

            BinarySplit binarySplit = bow.Clustering;

            string   str = binarySplit.Clusters.Proportions.ToCSharp();
            double[] expectedProportions = new double[] { 0.158034849951597, 0.11810261374637, 0.0871248789932236, 0.116408518877057, 0.103581800580833, 0.192642787996128, 0.0365440464666021, 0.0716360116166505, 0.0575992255566312, 0.058325266214908 };

            Assert.IsTrue(binarySplit.Clusters.Proportions.IsEqual(expectedProportions, 1e-10));
            Assert.IsTrue(binarySplit.Clusters.Covariances.All(x => x == null));

            Assert.AreEqual(features.GetLength(), new[] { 6, 10 });

            str = features.ToCSharp();

            double[][] expected = new double[][]
            {
                new double[] { 73, 36, 41, 50, 7, 106, 23, 22, 22, 29 },
                new double[] { 76, 93, 25, 128, 86, 114, 20, 91, 22, 72 },
                new double[] { 106, 47, 67, 57, 37, 131, 33, 31, 22, 21 },
                new double[] { 84, 41, 49, 59, 33, 73, 32, 50, 6, 33 },
                new double[] { 169, 105, 92, 47, 95, 67, 16, 25, 83, 20 },
                new double[] { 145, 166, 86, 140, 170, 305, 27, 77, 83, 66 }
            };

            for (int i = 0; i < features.Length; i++)
            {
                for (int j = 0; j < features[i].Length; j++)
                {
                    Assert.IsTrue(expected[i].Contains(features[i][j]));
                }
            }

            #region doc_classification_clustering

            // Now, the features can be used to train any classification
            // algorithm as if they were the images themselves. For example,
            // let's assume the first three images belong to a class and
            // the second three to another class. We can train an SVM using

            int[] labels = { -1, -1, -1, +1, +1, +1 };

            // Create the SMO algorithm to learn a Linear kernel SVM
            var teacher = new SequentialMinimalOptimization <Linear>()
            {
                Complexity = 10000 // make a hard margin SVM
            };

            // Obtain a learned machine
            var svm = teacher.Learn(features, labels);

            // Use the machine to classify the features
            bool[] output = svm.Decide(features);

            // Compute the error between the expected and predicted labels
            double error = new ZeroOneLoss(labels).Loss(output); // should be 0
            #endregion

            Assert.AreEqual(error, 0);
        }
Beispiel #15
0
        private void button4_Click(object sender, EventArgs e)
        {
            var path = new DirectoryInfo(dataPath + "BoW");
            //var path = new DirectoryInfo(@"C:\tmp\Accord\Resources");
            Dictionary <string, Bitmap> train      = new Dictionary <string, Bitmap>();
            Dictionary <string, Bitmap> test       = new Dictionary <string, Bitmap>();
            Dictionary <string, Bitmap> all        = new Dictionary <string, Bitmap>();
            Dictionary <string, int>    labelIndex = new Dictionary <string, int>();

            int labelCount = 0;

            foreach (DirectoryInfo classFolder in path.EnumerateDirectories())
            {
                string name = classFolder.Name;
                labelIndex[name] = ++labelCount;
                logDebug(name + " " + labelIndex[name]);
                FileInfo[] files = Utils.GetFilesByExtensions(classFolder, ".jpg", ".png").ToArray();
                Vector.Shuffle(files);
                for (int i = 0; i < files.Length; i++)
                {
                    FileInfo file  = files[i];
                    Bitmap   image = (Bitmap)Bitmap.FromFile(file.FullName);
                    if ((i / (double)files.Length) < 0.7)
                    {
                        // Put the first 70% in training set
                        train.Add(file.FullName, image);
                    }
                    else
                    {
                        // Put the restant 30% in test set
                        test.Add(file.FullName, image);
                    }
                    all.Add(file.FullName, image);
                    logDebug(file.FullName);
                }
            }

            int numberOfWords = 36;
            IBagOfWords <Bitmap> bow;
            BinarySplit          binarySplit = new BinarySplit(numberOfWords);

            // Create bag-of-words (BoW) with the given algorithm
            BagOfVisualWords surfBow = new BagOfVisualWords(binarySplit);

            // Compute the BoW codebook using training images only
            bow = surfBow.Learn(train.Values.ToArray());
            logDebug("BOW Done");

            List <double[]> lstInput  = new List <double[]>();
            List <int>      lstOutput = new List <int>();

            // Extract Feature in bother training and testing
            foreach (String fileName  in train.Keys)
            {
                double[] featureVector = (bow as ITransform <Bitmap, double[]>).Transform(train[fileName]);
                //string featureString = featureVector.ToString(DefaultArrayFormatProvider.InvariantCulture);
                //logDebug(featureString);
                lstInput.Add(featureVector);
                //FileInfo fin = new FileInfo(fileName);
                String labelString = Path.GetFileName(Path.GetDirectoryName(fileName));
                lstOutput.Add(labelIndex[labelString]);
            }
            //this.ksvm = teacher.Learn(inputs, outputs);

            double[][] inputs  = lstInput.ToArray();
            int[]      outputs = lstOutput.ToArray();

            IKernel kernel = new ChiSquare();

            MulticlassSupportVectorLearning <IKernel> teacher = new MulticlassSupportVectorLearning <IKernel>()
            {
                Kernel  = kernel,
                Learner = (param) =>
                {
                    return(new SequentialMinimalOptimization <IKernel>()
                    {
                        Kernel = kernel,
                        Complexity = 1.0,
                        Tolerance = 0.01,
                        CacheSize = 500,
                        Strategy = SelectionStrategy.Sequential,
                    });
                }
            };
            var ksvm = teacher.Learn(inputs, outputs);

            logDebug("ksvm Done");
            double error = new ZeroOneLoss(outputs).Loss(ksvm.Decide(inputs));

            logDebug("error=" + error);

            int trainingHit  = 0;
            int trainintMiss = 0;
            // For each image group (i.e. flowers, dolphins)
            Dictionary <string, Bitmap> data = train;

            foreach (String fileName in data.Keys)
            {
                double[] input       = (bow as ITransform <Bitmap, double[]>).Transform(data[fileName]);
                String   labelString = Path.GetFileName(Path.GetDirectoryName(fileName));
                int      label       = labelIndex[labelString];

                int actual = ksvm.Decide(input);
                if (label == actual)
                {
                    trainingHit++;
                }
                else
                {
                    trainintMiss++;
                    logDebug(labelString + " " + String.Format("{0} {1}", label, actual));
                }
            }
            logDebug(String.Format("Result {0}/{1}", trainingHit, data.Count));
        }
        public void binary_split_information_test()
        {
            // Use a fixed seed for reproducibility
            Accord.Math.Random.Generator.Seed = 0;

            // Declare some data to be clustered
            double[][] input =
            {
                new double[] { -5, -2, -1 },
                new double[] { -5, -5, -6 },
                new double[] {  2,  1,  1 },
                new double[] {  1,  1,  2 },
                new double[] {  1,  2,  2 },
                new double[] {  3,  1,  2 },
                new double[] { 11,  5,  4 },
                new double[] { 15,  5,  6 },
                new double[] { 10,  5,  6 },
            };

            // Create a new binary split with 3 clusters
            BinarySplit binarySplit = new BinarySplit(3)
            {
                ComputeProportions = true,
                ComputeCovariances = true,
                ComputeError       = true,
            };

            // Learn a data partitioning using the Binary Split algorithm
            KMeansClusterCollection clustering = binarySplit.Learn(input);

            string str = clustering.Proportions.ToCSharp();

            double[] expectedProportions = new double[] { 0.333333333333333, 0.444444444444444, 0.222222222222222 };
            Assert.IsTrue(expectedProportions.IsEqual(clustering.Proportions, 1e-10));

            var strs = clustering.Covariances.Apply(x => x.ToCSharp());

            double[][][] expectedCovar =
            {
                new double[][]
                {
                    new double[] {                   7,                  0,                   1 },
                    new double[] {                   0,                  0,                   0 },
                    new double[] {                   1,                  0,    1.33333333333333 }
                },
                new double[][]
                {
                    new double[] {   0.916666666666667,              -0.25, -0.0833333333333333 },
                    new double[] {               -0.25,               0.25,  0.0833333333333333 },
                    new double[] { -0.0833333333333333, 0.0833333333333333,                0.25 }
                },
                new double[][]
                {
                    new double[] {                   0,                  0,                   0 },
                    new double[] {                   0,                4.5,                 7.5 },
                    new double[] {                   0,                7.5,                12.5 }
                }
            };

            Assert.IsTrue(expectedCovar.IsEqual(clustering.Covariances, 1e-10));
        }