/// <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++; }