Пример #1
0
        /// <summary>
        /// Face recognition based on Priciple Component Analysis (PCA)
        /// classifier using eigenfaces
        /// </summary>
        /// <param name="labels">The set of labels in the training set</param>
        /// <param name="trainingImages">The set of images(faces) in the
        /// training set</param>
        /// <param name="face">The face detected in gray scale
        /// to be recognized. The dimension of the image must be
        /// equal to the dimension of the images in the training set</param>
        /// <returns>A string representing the label of the face recognized
        /// or an empty string if no matches were found</returns>
        public String recognizeEigenFace(List <String> labels,
                                         List <Image <Gray, Byte> > trainingImages,
                                         Bitmap face)
        {
            String label       = String.Empty;
            int    numTraining = trainingImages.ToArray().Length;

            InitParams();
            Image <Bgr, Byte>  imageEmgu     = new Image <Bgr, Byte>(face);
            Image <Gray, Byte> extractedFace = imageEmgu.Convert <Gray, Byte>().Copy().Resize(
                100, 100, INTER.CV_INTER_CUBIC);

            extractedFace._EqualizeHist();

            if (numTraining != 0)
            {
                //TermCriteria for face recognition with numbers of trained
                //images like maxIteration
                MCvTermCriteria termCrit = new MCvTermCriteria(numTraining, Eps);

                //Eigen face recognizer
                EigenObjectRecognizer recognizer = new EigenObjectRecognizer(
                    trainingImages.ToArray(),
                    labels.ToArray(),
                    Treshold,
                    ref termCrit);
                EigenObjectRecognizer.RecognitionResult r;
                r = recognizer.Recognize(extractedFace);
                if (r != null)
                {
                    label                   = r.Label;
                    MostSimilarFace         = trainingImages[r.Index];
                    MostSimilarFaceIndex    = r.Index;
                    MostSimilarFaceDistance = r.Distance;
                    MostSimilarFaceLabel    = r.Label;
                }
                else
                {
                    float[] distances = recognizer.GetEigenDistances(extractedFace);
                    int     minIndex  = 0;
                    float   minVal    = distances[0];
                    for (int i = 1; i < distances.Length; i++)
                    {
                        if (distances[i] < minVal)
                        {
                            minVal   = distances[i];
                            minIndex = i;
                        }
                        MostSimilarFace         = trainingImages[minIndex];
                        MostSimilarFaceIndex    = minIndex;
                        MostSimilarFaceDistance = minVal;
                        MostSimilarFaceLabel    = labels[minIndex];
                    }
                }
            }

            return(label);
        }
        public void capture()
        {
            this.log("capturing...");
            Image <Bgr, Byte>  currentFrame = grabber.QueryFrame().Resize(320, 240, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);
            Image <Gray, byte> gray         = currentFrame.Convert <Gray, Byte>();

            this.log("capture done");

            // check train done
            if (this.frameCount % 10 == 0 && this.trainCount >= 0 && this.trainCount < TRAIN_THRESHOLD)
            {
                if (this.train(gray, this.personToTrain))
                {
                    this.trainCount++;
                    this.log("training..." + trainCount);
                }
                this.match("", TRAINING);
                return;
            }
            else if (this.trainCount == TRAIN_THRESHOLD)
            {
                MCvTermCriteria termCrit = new MCvTermCriteria(50, 0.001);
                recognizer = new EigenObjectRecognizer(this.appPath, trainingImages.ToArray(), this.labels.ToArray(), 5000, ref termCrit);

                this.trainComplete();
                this.trainCount = -1;
            }


            // Face detect
            this.log("face detecting...");
            Image <Gray, byte> result;

            MCvAvgComp[][] facesDetected = gray.DetectHaarCascade(face, 1.2, 10, Emgu.CV.CvEnum.HAAR_DETECTION_TYPE.DO_CANNY_PRUNING, new Size(20, 20));
            this.log("face detecting done");

            // find the best matched again.
            if (facesDetected[0].Length != 1)
            {
                this.log("no faces detected");
                this.match(this.bestMatchPerson, 0);

                if (this.frameCount % NOFACE_COUNT == 0)
                {
                    this.matchPersons.Clear();
                    this.bestMatchPerson = "";
                    this.log("reset");
                    this.match("", 0);

                    // clean up all apps when no use
                    if (this.frameCount % CLEANUP_COUNT == 0)
                    {
                        this.cleanup();
                    }
                }
            }
            else
            {
                this.log("faces detected");

                foreach (MCvAvgComp f in facesDetected[0])
                {
                    result = currentFrame.Copy(f.rect).Convert <Gray, byte>().Resize(100, 100, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC);

                    // Find the best match person
                    int testCount = 0;
                    foreach (KeyValuePair <string, int> iter in this.matchPersons)
                    {
                        testCount += iter.Value;
                    }

                    if (trainingImages.ToArray().Length != 0)
                    {
                        string name = recognizer.Recognize(result, testCount, TRAIN_THRESHOLD);
                        this.log("found:" + name + ", maxCount:" + testCount);

                        // Find the best match until threshold
                        if (testCount < MATCH_THRESHOLD)
                        {
                            if (this.matchPersons.ContainsKey(name))
                            {
                                this.matchPersons[name]++;
                            }
                            else
                            {
                                this.matchPersons[name] = 1;
                            }

                            this.match("", testCount);
                        }
                        else
                        {
                            IEnumerable <KeyValuePair <string, int> > sortedDict = from entry in matchPersons orderby entry.Value descending select entry;
                            string matchPersonsOut = "";
                            string bestMatch       = "";
                            int    i = 0;
                            foreach (KeyValuePair <string, int> iter in sortedDict)
                            {
                                matchPersonsOut += iter.Key + ": " + iter.Value + "\n";
                                if (i++ == 0)
                                {
                                    if (iter.Value >= 7)
                                    {
                                        bestMatch            = iter.Key;
                                        this.bestMatchPerson = bestMatch;
                                    }
                                    else
                                    {
                                        this.matchPersons.Clear();
                                        this.bestMatchPerson = "";
                                        this.log("cannot find the person over 7");
                                    }
                                }
                            }
                            this.match(bestMatch, testCount);

                            this.logger(matchPersonsOut);
                        }
                    }
                }
            }
            this.frameCount++;
        }