예제 #1
0
        /// <summary>
        /// Calculates accuracy of the PCA Classifier
        /// </summary>
        /// <param name="testingPath"> Location of the Testing Files</param>
        /// <param name="decision"> Whether ClossestNeighbor or KNN</param>
        /// <param name="measureType"> Wether Euclidean or Projection</param>
        /// <param name="numberNeighbs"> How many neighbors to take into account for KNN</param>
        /// <returns></returns>
        public double Accuracy(String testingPath, DecisionType decision, ClossenessMeasure measureType, int numberNeighbs)
        {
            List <ATTFace> testingFaces = DataUnit.GetTestingData(testingPath);
            double         accu         = 0;

            foreach (ATTFace testFace in testingFaces)
            {
                int            guessID   = 0;
                List <ATTFace> bestFaces = new List <ATTFace>();
                FindBestMatch(testFace.ImageVector, decision, measureType, ref bestFaces, ref guessID, neighborNumber: numberNeighbs);
                if (guessID == testFace.personID)
                {
                    accu += 1;
                }
            }
            return(accu / testingFaces.Count);
        }
예제 #2
0
        /// <summary>
        /// Finds the Best Match(es) as a list, and provides a guessed Person ID.
        /// </summary>
        /// <param name="imageAsVector"> Image of the person to be classified.</param>
        /// <param name="decisionType"> Either ClossestNeighbor or KKN</param>
        /// <param name="measureType"> Either Euclidean or Projection. Determines which measurement is to be used.</param>
        /// <param name="BestFaces"> List of ATTFaces passed by reference. Must be empty. BestMatches added to the list if onlyID = false</param>
        /// <param name="guessID">int passed by reference. The class of the person images guessed by PCA.</param>
        /// <param name="neighborNumber"> How many neighbors to use for KNN. Default is 3</param>
        /// <param name="numberFaces">How many Best Matches to add to BestFaces. Default is 6</param>
        /// <param name="onlyID"> Whether ONLY the class of the person is of interest. If the BestFaces are also of interest, set to false/</param>
        public void FindBestMatch(double[] imageAsVector, DecisionType decisionType, ClossenessMeasure measureType, ref List <ATTFace> BestFaces, ref int guessID, int neighborNumber = 3, int numberFaces = 6, bool onlyID = true)
        {
            double[] meanAdjusted   = SubstractArrays(imageAsVector, MeanFaceAsArray);
            double[] projectedImage = ComputeProjection(meanAdjusted);
            foreach (ATTFace Person in DataSet)
            {
                double similarity;
                if (measureType == ClossenessMeasure.Euclidean)
                {
                    similarity       = EuclideanDistance(Person.ImageVectorTransformed, projectedImage);
                    Person.Closeness = similarity;
                }
                else if (measureType == ClossenessMeasure.Projection)
                {
                    similarity       = DotProduct(Person.ImageVectorTransformed, projectedImage);
                    Person.Closeness = -similarity; //A maximization is transformed to a minimization by putting a -
                }
                else
                {
                    throw new ArgumentException("ClosenessMeasure is not supported!");
                }
            }

            DataSet.Sort();

            // ------------------------------------------ Retrieving best guess ------------------------------//
            if (decisionType == DecisionType.ClossestNeighbor)
            {
                guessID = DataSet[0].personID;
            }
            else if (decisionType == DecisionType.KNN)
            {
                IDictionary <int, int> Tally = new Dictionary <int, int>();
                int maxVotes = 0;
                guessID = -1;
                for (int i = 0; i < neighborNumber; i++)
                {
                    ATTFace Person = DataSet[i];
                    if (Tally.ContainsKey(Person.personID))
                    {
                        Tally[Person.personID]++;
                        if (Tally[Person.personID] > maxVotes)
                        {
                            //To be here, a personID needs at leats two votes
                            maxVotes = Tally[Person.personID];
                            guessID  = Person.personID;
                        }
                    }
                    else
                    {
                        Tally.Add(Person.personID, 1);
                    }
                }
            }
            else
            {
                throw new ArgumentException("DecisionType not valid!");
            }

            // ---------------------------- Populating the list onlyID = False ----------------//
            if (!onlyID)
            {
                for (int i = 0; i < numberFaces; i++)
                {
                    BestFaces.Add((ATTFace)DataSet[i].Clone());
                }
            }
        }