예제 #1
0
        /// [1:N]
        /// <summary>
        /// Compara uma <see cref="Pessoa"/> contra um conjunto de outras <see cref="Pessoa"/>s e retorna o(s) melhore(s) match(s)
        /// </summary>
        /// <param name="probe">pessoa para procurar na base de dados</param>
        /// <param name="candidates">base de dados de pessoas a ser pesquisado</param>
        /// <returns>Todo objeto <see cref="Pessoa"/> correspondente na base de dados ou vazio se
        /// não existir match. Os resultados são classificados por pontuação em ordem decrescente. Se voce precisar apenas do melhor match,
        /// chame o método <see cref="Enumerable.FirstOrDefault{T}(IEnumerable{T})"/> na base de dados retornada.</returns>
        /// <remarks>
        /// <para>
        /// Compare o probe<see cref="Pessoa"/> para todos os candidatos <see cref="Pessoa"/>s e retorne o candidato mais similar.
        /// Chamando <see cref="Identificar"/>é quase a mesma coisa que chamar o <see cref="Verificar"/> em um loop
        /// exceto que o <see cref="Identificar"/> é bem mais rapido que o loop do <see cref="Verificar"/>.
        /// Se não houver candidato ou pontuação igual ou maior que o <see cref="Threshold"/>, <see cref="Identificar"/> retorna
        /// uma base de dados vazia.
        /// </para>
        /// <para>
        /// A maioria das aplicações precisam apenas do melhor match que pode ser obtido chamando o método
        /// <see cref="Enumerable.FirstOrDefault{T}(IEnumerable{T})"/> na base de dados retornada.
        /// Pontuação correspondente para cada<see cref="Pessoa"/> retornado pode ser obtido chamando o
        /// <see cref="Verificar"/> no probe <see cref="Pessoa"/> e o matching <see cref="Pessoa"/>.
        /// </para>
        /// <para>
        /// <see cref="Pessoa"/>s que passar por esse método deve ter o <see cref="Fingerprint.Template"/> valido.
        /// para cada <see cref="Fingerprint"/>, i.e. eles precisam ter passado pelo método <see cref="Extrair"/> antes.
        /// </para>
        /// </remarks>
        /// <seealso cref="Threshold"/>
        /// <seealso cref="MinMatches"/>
        /// <seealso cref="Verificar"/>
        public IEnumerable <Pessoa> Identificar(Pessoa probe, IEnumerable <Pessoa> candidates)
        {
            probe.CheckForNulls();
            Pessoa[] candidateArray = candidates.ToArray();
            BestMatchSkipper.PersonsSkipScore[] results;
            lock (this)
            {
                BestMatchSkipper collector = new BestMatchSkipper(candidateArray.Length, MinMatches - 1);
                Parallel.ForEach(probe.Fingerprints, probeFp =>
                {
                    List <int> personsByFingerprint    = new List <int>();
                    List <Template> candidateTemplates = FlattenHierarchy(candidateArray, probeFp.Dedo, out personsByFingerprint);

                    ParallelMatcher.PreparedProbe probeIndex = Matcher.Prepare(probeFp.Decoded);
                    float[] scores = Matcher.Match(probeIndex, candidateTemplates);

                    lock (collector)
                        for (int i = 0; i < scores.Length; ++i)
                        {
                            collector.AddScore(personsByFingerprint[i], scores[i]);
                        }
                });
                results = collector.GetSortedScores();
            }
            return(GetMatchingCandidates(candidateArray, results));
        }
예제 #2
0
        /// [1:1]
        /// <summary>
        /// Calcular o score de similaridade entre duas <see cref="Pessoa"/>s.
        /// </summary>
        /// <param name="probe">Primeira das duas pessoas para comparar</param>
        /// <param name="candidate">Segunda das duas pessoas para comparar</param>
        /// <returns> o índice de Similaridade indicando semelhança entre as duas pessoas ou 0 if se não existir match.</returns>
        /// <remarks>
        /// <para>
        /// O método <see cref="Verificar"/> compara duas <see cref="Pessoa"/>s, <see cref="Fingerprint"/> pela <see cref="Fingerprint"/>, e retorna
        /// um [float] indice de similaridade que indica o grau de semelhança entre
        /// as duas <see cref="Pessoa"/>s. Se esse score ficar abaixo do <see cref="Threshold"/>, o método <see cref="Verificar"/> retorna zero matchs.
        /// </para>
        /// <para>
        /// <see cref="Pessoa"/>s que passam por esse método devem ter o <see cref="Fingerprint.Template"/> valido
        /// para toda <see cref="Fingerprint"/>, i.e. devem ser passados pelo método <see cref="Extrair"/> antes.
        /// </para>
        /// </remarks>
        /// <seealso cref="Threshold"/>
        /// <seealso cref="MinMatches"/>
        /// <seealso cref="Identificar"/>
        public float Verificar(Pessoa probe, Pessoa candidate)
        {
            lock (this)
            {
                probe.CheckForNulls();
                candidate.CheckForNulls();
                BestMatchSkipper collector = new BestMatchSkipper(1, MinMatches - 1);
                Parallel.ForEach(probe.Fingerprints, probeFp =>
                {
                    var candidateTemplates = (from candidateFp in candidate.Fingerprints
                                              where IsCompatibleFinger(probeFp.Dedo, candidateFp.Dedo)
                                              select candidateFp.Decoded).ToList();

                    ParallelMatcher.PreparedProbe probeIndex = Matcher.Prepare(probeFp.Decoded);
                    float[] scores = Matcher.Match(probeIndex, candidateTemplates);

                    lock (collector)
                        foreach (float score in scores)
                        {
                            collector.AddScore(0, score);
                        }
                });

                return(ApplyThreshold(collector.GetSkipScore(0)));
            }
        }