Example #1
0
        public static CascadeClassifier Load(string filename)
        {
            XmlDocument doc = new XmlDocument();

            doc.Load(filename);

            XmlNode cascadeNode = doc.SelectSingleNode("CascadeClassifier");
            int     width       = int.Parse(cascadeNode.Attributes["Width"].Value);
            int     height      = int.Parse(cascadeNode.Attributes["Height"].Value);
            int     stageCount  = int.Parse(cascadeNode.Attributes["StageCount"].Value);

            //XmlNodeList stageList = doc.SelectNodes("Stage");
            StageClassifier[] classifiers = new StageClassifier[stageCount];
            for (int i = 0; i < stageCount; i++)
            {
                XmlNode stageNode = cascadeNode.ChildNodes[i];
                string  numStr    = (i + 1).ToString();

                if (false == numStr.Equals(stageNode.Attributes["StageNum"].Value))
                {
                    throw new Exception("Xml文件损坏");
                }
                classifiers[i] = LoadStageClassifier(i + 1, stageNode);
            }

            CascadeClassifier cascade = new CascadeClassifier();

            cascade.LoadFrom(new Size(width, height), classifiers);

            return(cascade);
        }
Example #2
0
        /// <summary>
        /// 计算强分类器的阈值
        /// </summary>
//         private void CalcThreshold()
//         {
//             MyFloat sum = 0;
//             foreach (WeakClassifier weak in _classifiers)
//             {
//                 sum += weak.Weight;
//             }
//             sum /= 2;
//             _threshold = sum;
//         }


        /// <summary>
        /// 调整强分类器的阈值,使得检测率满足要求
        /// </summary>
        /// <param name="result"></param>
        /// <param name="targetHitRate"></param>
//         private void AdjustThreshold(PredictResult result,MyFloat targetHitRate)
//         {
//             _trainPredictValues.Sort();
//             int targetHitCount = (int)(result.Count * targetHitRate + 0.5f);
//             int currentHitCount = (int)(result.Count * result.HitRate);
//             int diff = targetHitCount - currentHitCount;
//             int newIndex = BinarySearch(_trainPredictValues, _threshold)-diff;
//             if (newIndex < 0)
//                 newIndex = 0;
//             else if (newIndex >= _trainPredictValues.Count)
//                 newIndex = _trainPredictValues.Count - 1;
//             _threshold = _trainPredictValues[newIndex];
//
//         }

        /// <summary>
        /// 二分查找,找到大于等于key且序号最小的元素
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="key">待查找的数值</param>
        /// <returns>找到的序号</returns>
//         int BinarySearch(List<MyFloat> arr, MyFloat key)
//         {
//             int low = 0, high = arr.Count - 1;
//             int mid = (low + high) / 2;
//
//             while (low <= high)
//             {
//                 mid = (high + low) / 2;
//                 if (arr[mid] == key)
//                 {
//                     break;
//                 }
//                 else if (arr[mid] < key)
//                 {
//                     low = mid + 1;
//                 }
//                 else
//                 {
//                     high = mid - 1;
//                 }
//             }
//             while (mid > 0 && arr[mid - 1] == key)
//                 mid--;
//             if (arr[mid] < key && mid + 1 < arr.Count && arr[mid + 1] > key)
//                 mid++;
//             return mid;
//         }


        internal static StageClassifier Load(int id, double threshold, WeakClassifier[] weaks)
        {
            StageClassifier stage = new StageClassifier();

            stage._id          = id;
            stage._threshold   = threshold;
            stage._classifiers = weaks;
            return(stage);
        }
Example #3
0
        private static StageClassifier LoadStageClassifier(int id, XmlNode stageNode)
        {
            MyFloat threshold = MyFloat.Parse(stageNode.Attributes["Threshold"].Value);
            int     weakNum   = int.Parse(stageNode.Attributes["ClassifiersNum"].Value);

            WeakClassifier[] weaks = new WeakClassifier[weakNum];
            for (int i = 0; i < weakNum; i++)
            {
                XmlNode weakNode = stageNode.ChildNodes[i];
                weaks[i] = LoadWeakClassifier(weakNode);
            }

            StageClassifier stage = StageClassifier.Load(id, threshold, weaks);

            return(stage);
        }
Example #4
0
        public void Train(SampleCollection posSamples,
                          SampleCollection allNegSamples,
                          SampleCollection validateSamples,
                          Size size,
                          double targetFalsePositiveRate, double maxFalsePositiveRate, double minHitRate)
        {
            const int startCapacity = 20;

            _size = size;
            List <StageClassifier> stageClassifier = new List <StageClassifier>(startCapacity);
            double hitRate           = 1;
            double falsePositiveRate = 1;
            int    stageCount        = 0;

            int maxSampleNum;
            SampleCollection negSamples;

            {   //计算使用的负样本数量
                double MaxMemoryUse = MemoryInfo.GetFreePhysicalMemory() - 400e6;
                if (MaxMemoryUse < 0)
                {
                    MaxMemoryUse = 1.8e9;
                }
                //MaxMemoryUse = 2.48e9;
                //按照内存大小来选取负样本,在充分利用内存的同时防止使用虚拟内存
                int weakNum = WeakClassifierManager.Instance.WeakClassifiers.Length;
                maxSampleNum = (int)((
                                         MaxMemoryUse
                                         - 1.5e6f //预留150M给程序其它部分
                                         )
                                     / weakNum / sizeof(MyFloat)) - posSamples.Count;

                if (DebugMsg.Debug)
                {
                    string msg = string.Format("\r\n单次使用负样本:{0},特征数量:{1},预计消耗内存:{2}M\r\n",
                                               maxSampleNum, weakNum, MaxMemoryUse / 1024 / 1024);
                    DebugMsg.AddMessage(msg, 0);
                }
            }

            //如果已有分类器,计算当前的性能
            if (_classifiers != null && _classifiers.Length > 0)
            {
                PredictResult result = EvaluateErrorRate(validateSamples);
                hitRate           = result.HitRate;
                falsePositiveRate = result.FalsePositiveRate;
                stageCount        = _classifiers.Length;
                stageClassifier.AddRange(_classifiers);

                negSamples = CreateNextSamples(allNegSamples, falsePositiveRate, maxSampleNum);

                if (DebugMsg.Debug)
                {
                    string msg = string.Format("载入分类器完成,层数:{0},当前性能为:\r\n检测率:\t{1:P5},\t误检率:\t{2:P5}\r\n------\r\n",
                                               stageCount, hitRate, falsePositiveRate);
                    DebugMsg.AddMessage(msg, 0);
                }
            }
            else
            {
                negSamples = allNegSamples.GetNegSamples(maxSampleNum);
            }

            while (falsePositiveRate > targetFalsePositiveRate && negSamples.Count != 0 && posSamples.Count != 0)
            {
                stageCount++;

                if (DebugMsg.Debug)
                {
                    string msg = string.Format("--------------------\r\n开始训练第{0}级分类器,使用的数量为:\r\n正样本:\t{1}\t负样本:\t{2}\r\n目标检测率:\t{3:P5}\t目标误检率:\t{4:P5}\r\n",
                                               stageCount, posSamples.Count, negSamples.Count, minHitRate, maxFalsePositiveRate);
                    DebugMsg.AddMessage(msg, 0);
                }

                StageClassifier currentStage = new StageClassifier(stageCount);
                PredictResult   result       = currentStage.Train(posSamples, negSamples, validateSamples,
                                                                  maxFalsePositiveRate, minHitRate);
                falsePositiveRate *= result.FalsePositiveRate;
                hitRate           *= result.HitRate;

                stageClassifier.Add(currentStage);
                _classifiers = stageClassifier.ToArray();

                if (DebugMsg.Debug)
                {
                    string msg = string.Format("------\r\n第{0}级分类器训练结束,当前性能为:\r\n检测率:\t{1:P5},\t误检率:\t{2:P5}\r\n弱分类器数量:{3}\r\n目前训练时间总计:{4}\r\n",
                                               stageCount, hitRate, falsePositiveRate, currentStage.WeakClassifierCount, DebugMsg.stopwatch.Elapsed.ToString());
                    DebugMsg.AddMessage(msg, 0);
                }
                if (falsePositiveRate > targetFalsePositiveRate)
                {
                    //posSamples = this.CreateNextSamples(posSamples);
                    validateSamples = this.GetPositivePredictedSamples(validateSamples);
                    negSamples      = CreateNextSamples(allNegSamples, falsePositiveRate, maxSampleNum);
                }
                this.Save(string.Format(@"D:\ccc{0}.xml", stageCount.ToString()));
            }

            if (DebugMsg.Debug)
            {
                DebugMsg.stopwatch.Stop();
                string msg = string.Format("\r\n--------------------\r\n全部训练完成,训练时间总计:{0}\r\n",
                                           DebugMsg.stopwatch.Elapsed.ToString());
                DebugMsg.AddMessage(msg, 0);
            }

            this.Save(@"D:\ccc.xml");
        }