예제 #1
0
        internal List <MtripletPair> FindNoRotateAllSimilar(MTriplet queryMTp)
        {
            // Indexing by MaxDistance
            double dThr   = MTriplet.DistanceThreshold;
            double d      = queryMTp.MaxDistance - dThr;
            int    iniIdx = BinarySearch(MTriplets, d);

            d = queryMTp.MaxDistance + dThr;

            var result = new List <MtripletPair>();

            for (int j = iniIdx; j < MTriplets.Count && MTriplets[j].MaxDistance <= d; j++)
            {
                MTriplet currMTp = MTriplets[j];
                byte[]   currOrder;
                double   currSim = queryMTp.NoRotateMatch(currMTp, out currOrder);
                if (currSim > 0)
                {
                    result.Add(new MtripletPair
                    {
                        queryMTp          = queryMTp,
                        templateMTp       = currMTp,
                        matchingValue     = currSim,
                        templateMtiaOrder = currOrder
                    }
                               );
                }
            }
            if (result.Count > 0)
            {
                return(result);
            }
            return(null);
        }
예제 #2
0
        private double MatchBetaAngles(MTriplet compareTo, byte[] order)
        {
            var    idxArr  = new[] { 0, 1, 2, 0 };
            double maxdiff = 0;

            for (int i = 0; i < 3; i++)
            {
                int     j      = idxArr[i + 1];
                Minutia qMtiai = minutiae[MtiaIdxs[i]];
                Minutia qMtiaj = minutiae[MtiaIdxs[j]];
                double  qbeta  = Angle.Difference2Pi(qMtiai.Angle, qMtiaj.Angle);

                Minutia tMtiai = compareTo.minutiae[compareTo.MtiaIdxs[order[i]]];
                Minutia tMtiaj = compareTo.minutiae[compareTo.MtiaIdxs[order[j]]];
                double  tbeta  = Angle.Difference2Pi(tMtiai.Angle, tMtiaj.Angle);

                double diff1 = Math.Abs(tbeta - qbeta);
                double diff  = Math.Min(diff1, 2 * Math.PI - diff1);
                if (diff >= aThr)
                {
                    return(0);
                }
                if (diff > maxdiff)
                {
                    maxdiff = diff;
                }
            }

            return(1 - maxdiff / aThr);
        }
예제 #3
0
        private int[] GetAlphaCodes(MTriplet mtp)
        {
            int[] alpha = new int[3];
            for (int i = 0; i < 3; i++)
            {
                int j;
                if (i == 2)
                {
                    j = 0;
                }
                else
                {
                    j = i + 1;
                }

                Minutia qMtiai  = mtp[i];
                Minutia qMtiaj  = mtp[j];
                double  x       = qMtiai.X - qMtiaj.X;
                double  y       = qMtiai.Y - qMtiaj.Y;
                double  angleij = Angle.ComputeAngle(x, y);
                double  qAlpha  = Angle.Difference2Pi(qMtiai.Angle, angleij);

                alpha[i] = DiscretizeAngle(qAlpha);
            }
            return(alpha);
        }
예제 #4
0
        /// <summary>
        ///     Extract features of type <see cref="MtripletsFeature"/> from the specified minutiae.
        /// </summary>
        /// <param name="minutiae">
        ///     The list of <see cref="Minutia"/> to extract the features from.
        /// </param>
        /// <returns>
        ///     Features of type <see cref="MtripletsFeature"/> extracted from the specified minutiae.
        /// </returns>
        public MtripletsFeature ExtractFeatures(List <Minutia> minutiae)
        {
            List <MTriplet>       result   = new List <MTriplet>();
            Dictionary <int, int> triplets = new Dictionary <int, int>();

            var nearest  = new short[minutiae.Count, neighborsCount];
            var distance = new double[minutiae.Count, neighborsCount];

            // Initializing distances
            for (int i = 0; i < minutiae.Count; i++)
            {
                for (int j = 0; j < neighborsCount; j++)
                {
                    distance[i, j] = double.MaxValue;
                    nearest[i, j]  = -1;
                }
            }

            // Computing m-triplets
            for (short i = 0; i < minutiae.Count; i++)
            {
                // Updating nearest minutiae
                UpdateNearest(minutiae, i, nearest, distance);

                // Building m-triplets
                for (int j = 0; j < neighborsCount - 1; j++)
                {
                    for (int k = j + 1; k < neighborsCount; k++)
                    {
                        if (nearest[i, j] != -1 && nearest[i, k] != -1)
                        {
                            if (i == nearest[i, j] || i == nearest[i, k] || nearest[i, j] == nearest[i, k])
                            {
                                throw new Exception("Wrong mtp");
                            }

                            MTriplet newMTriplet = new MTriplet(new short[] { i, nearest[i, j], nearest[i, k] }, minutiae);
                            int      newHash     = newMTriplet.GetHashCode();
                            if (!triplets.ContainsKey(newHash))
                            {
                                triplets.Add(newHash, 0);
                                result.Add(newMTriplet);
                            }
                        }
                    }
                }
            }
            result.TrimExcess();
            return(new MtripletsFeature(result, minutiae));
        }
예제 #5
0
        public double NoRotateMatch(MTriplet target, out byte[] mtiaOrder)
        {
            byte[] matchOrder = null;
            double maxSimil   = 0;

            if (Math.Abs(MaxDistance - target.MaxDistance) < dThr && Math.Abs(MidDistance - target.MidDistance) < dThr && Math.Abs(MinDistance - target.MinDistance) < dThr /* && Angle.AngleDif180(maxBeta, target.maxBeta) < aThr*/)
            {
                foreach (byte[] order in Orders)
                {
                    double dirSim = MatchMtiaDirections(target, order);
                    if (dirSim == 0)
                    {
                        continue;
                    }

                    double distSim = MatchDistances(target, order);
                    if (distSim == 0)
                    {
                        continue;
                    }

                    double betaSim = MatchBetaAngles(target, order);
                    if (betaSim == 0)
                    {
                        continue;
                    }

                    double alphaSim = MatchAlphaAngles(target, order);
                    if (alphaSim == 0)
                    {
                        continue;
                    }

                    double currentSimil = 1 - (1 - distSim) * (1 - alphaSim) * (1 - betaSim);

                    if (currentSimil > maxSimil)
                    {
                        matchOrder = order;
                        maxSimil   = currentSimil;
                    }
                }
            }
            mtiaOrder = matchOrder;
            return(maxSimil);
        }
예제 #6
0
        private int[] GetAllRotationsHashes(MTriplet mtp)
        {
            // Computing hash for alpha angles
            int[] alphaCodes = GetAlphaCodes(mtp);

            // Generating all possible hashes
            int[] hashes = new int[3];
            int   i      = 0;

            foreach (byte[] order in MTriplet.Orders)
            {
                int a0 = alphaCodes[order[0]];
                int a1 = alphaCodes[order[1]];
                int a2 = alphaCodes[order[2]];
                hashes[i++] = MergeHashes(a0, a1, a2);
            }
            return(hashes);
        }
예제 #7
0
        private double MatchAlphaAngles(MTriplet compareTo, byte[] order)
        {
            double maxdiff = 0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (i != j)
                    {
                        Minutia qMtiai  = minutiae[MtiaIdxs[i]];
                        Minutia qMtiaj  = minutiae[MtiaIdxs[j]];
                        double  x       = qMtiai.X - qMtiaj.X;
                        double  y       = qMtiai.Y - qMtiaj.Y;
                        double  angleij = Angle.ComputeAngle(x, y);
                        double  qAlpha  = Angle.Difference2Pi(qMtiai.Angle, angleij);

                        Minutia tMtiai = compareTo.minutiae[compareTo.MtiaIdxs[order[i]]];
                        Minutia tMtiaj = compareTo.minutiae[compareTo.MtiaIdxs[order[j]]];
                        x       = tMtiai.X - tMtiaj.X;
                        y       = tMtiai.Y - tMtiaj.Y;
                        angleij = Angle.ComputeAngle(x, y);
                        double tAlpha = Angle.Difference2Pi(tMtiai.Angle, angleij);

                        double diff1 = Math.Abs(tAlpha - qAlpha);
                        double diff  = Math.Min(diff1, 2 * Math.PI - diff1);
                        if (diff >= aThr)
                        {
                            return(0);
                        }
                        if (diff > maxdiff)
                        {
                            maxdiff = diff;
                        }
                    }
                }
            }

            return(1 - maxdiff / aThr);
        }
예제 #8
0
        private double MatchDistances(MTriplet compareTo, byte[] order)
        {
            double diff0 = Math.Abs(d[0] - compareTo.d[order[0]]);

            if (diff0 > dThr)
            {
                return(0);
            }
            double diff1 = Math.Abs(d[1] - compareTo.d[order[1]]);

            if (diff1 > dThr)
            {
                return(0);
            }
            double diff2 = Math.Abs(d[2] - compareTo.d[order[2]]);

            if (diff2 > dThr)
            {
                return(0);
            }
            return(1 - (Math.Max(diff0, Math.Max(diff1, diff2))) / dThr);
        }
예제 #9
0
        private double MatchMtiaDirections(MTriplet compareTo, byte[] order)
        {
            double maxdiff = 0;

            for (int i = 0; i < 3; i++)
            {
                Minutia qMtiai = minutiae[MtiaIdxs[i]];
                Minutia tMtiai = compareTo.minutiae[compareTo.MtiaIdxs[order[i]]];
                double  alpha  = qMtiai.Angle;
                double  beta   = tMtiai.Angle;
                double  diff1  = Math.Abs(beta - alpha);
                double  diff   = Math.Min(diff1, 2 * Math.PI - diff1);
                if (diff >= Math.PI / 4)
                {
                    return(0);
                }
                if (diff > maxdiff)
                {
                    maxdiff = diff;
                }
            }

            return(1);
        }