コード例 #1
0
        public void AddClassifier(StrongClassifier classifier)
        {
            if (classifier.WeakClassifiers.Count == 0)
            {
                throw new ArgumentException("Classifier cannot have 0 features", nameof(classifier.WeakClassifiers));
            }

            Classifiers.Add(classifier);
        }
コード例 #2
0
        /// <summary>
        /// Viola Jones Cascade Classifier Training Method
        /// </summary>
        /// <param name="features">Haar-Features</param>
        /// <param name="images">Image data</param>
        /// <param name="results">Results data</param>
        /// <param name="f">Maximum false positive rate</param>
        /// <param name="d">Minimum detection rate</param>
        /// <param name="fTarget">Target overall false positive rate</param>
        public void Train(List <WeakClassifier> features, double[][,] images, bool[] results, double f, double d, double fTarget, double[][,] validImages, bool[] validResults)
        {
            Classifiers = new List <StrongClassifier>();
            var imagesCpy  = images.Clone() as double[][, ]; // copy not to damage original images
            var resultsCpy = results.Clone() as bool[];      // copy not to damage original results

            var integralValidImages = IntegrateImages(validImages);

            var falsePositiveRates = new List <double>();

            falsePositiveRates.Add(1.0);

            var detectionRates = new List <double>();

            detectionRates.Add(1.0);

            var i = 0;

            Console.WriteLine("*********Traning of the cascade classifier started*********");

            // Train Cascade Classifier
            while (falsePositiveRates[i] > fTarget)
            {
                // Strong classifiers counter
                i++;

                // WeakClassifiers counter
                var n = 0;
                falsePositiveRates.Add(falsePositiveRates.Last());
                detectionRates.Add(0.0);

                // Train Strong Classifier
                var sc = new StrongClassifier();
                while (falsePositiveRates[i] > f * falsePositiveRates[i - 1])
                {
                    n++;

                    Console.Write("    ");

                    // Train Strong Classifier with n Weak Classifiers
                    sc.AddWeakClassifier(imagesCpy, resultsCpy, features);
                    Classifiers.Add(sc);

                    var detectionRate     = 0.0;
                    var falsePositiveRate = 0.0;

                    // Evaluate current cascade classifier to determine detection rate and false positives rate
                    Evaluate(integralValidImages, validResults, out falsePositiveRate, out detectionRate);

                    detectionRates[i]     = detectionRate;
                    falsePositiveRates[i] = falsePositiveRate;

                    while (detectionRate < d * detectionRates[i - 1])
                    {
                        // Decrease Threshold by 0.001
                        sc.DecreaseThreshold();

                        Evaluate(integralValidImages, validResults, out falsePositiveRate, out detectionRate);

                        detectionRates[i]     = detectionRate;
                        falsePositiveRates[i] = falsePositiveRate;
                    }

                    Classifiers.Remove(sc);
                }

                Classifiers.Add(sc);

                Console.WriteLine("Strong classifier was added. Number of weak classifiers: {0} Detection Rate: {1} False Positive Rate: {2}",
                                  sc.WeakClassifiers.Count.ToString().PadRight(10),
                                  Math.Round(detectionRates[i], 4).ToString().PadRight(10),
                                  Math.Round(falsePositiveRates[i], 4).ToString().PadRight(10));

                // Get images that were classified incorrectly
                var posImages  = new List <double[, ]>();
                var posResults = new List <bool>();
                for (int j = 0; j < imagesCpy.Length; j++)
                {
                    var classifierResult = sc.Detect(imagesCpy[j]);

                    if (classifierResult)
                    {
                        posImages.Add(imagesCpy[j]);
                        posResults.Add(resultsCpy[j]);
                    }
                }

                imagesCpy  = posImages.ToArray();
                resultsCpy = posResults.ToArray();

                if (falsePositiveRates[i] > fTarget)
                {
                    var fDetImgs    = new List <double[, ]>();
                    var fDetResults = new List <bool>();

                    for (int j = 0; j < validImages.Length; j++)
                    {
                        var result = Detect(validImages[j]);

                        if (result != validResults[j] && result)
                        {
                            fDetImgs.Add(validImages[j]);
                            fDetResults.Add(validResults[j]);
                        }
                    }

                    var toTakeCount = new int[] { resultsCpy.Count(r => r) - resultsCpy.Count(r => !r), fDetImgs.Count }.Where(x => x >= 0).Min();

                    fDetImgs = fDetImgs.Take(toTakeCount).ToList();
                    fDetImgs.AddRange(imagesCpy);
                    imagesCpy = fDetImgs.ToArray();

                    fDetResults = fDetResults.Take(toTakeCount).ToList();
                    fDetResults.AddRange(resultsCpy);
                    resultsCpy = fDetResults.ToArray();
                }
            }

            Console.WriteLine("*********Traning of the cascade classifier ended*********");

            Statistics(images, results);
        }