Esempio n. 1
0
        static NeighborhoodType[] NeighborhoodTypes()
        {
            var types = new NeighborhoodType[256];

            for (uint mask = 0; mask < 256; ++mask)
            {
                bool TL         = (mask & 1) != 0;
                bool TC         = (mask & 2) != 0;
                bool TR         = (mask & 4) != 0;
                bool CL         = (mask & 8) != 0;
                bool CR         = (mask & 16) != 0;
                bool BL         = (mask & 32) != 0;
                bool BC         = (mask & 64) != 0;
                bool BR         = (mask & 128) != 0;
                uint count      = Integers.PopulationCount(mask);
                bool diagonal   = !TC && !CL && TL || !CL && !BC && BL || !BC && !CR && BR || !CR && !TC && TR;
                bool horizontal = !TC && !BC && (TR || CR || BR) && (TL || CL || BL);
                bool vertical   = !CL && !CR && (TL || TC || TR) && (BL || BC || BR);
                bool end        = (count == 1);
                if (end)
                {
                    types[mask] = NeighborhoodType.Ending;
                }
                else if (!diagonal && !horizontal && !vertical)
                {
                    types[mask] = NeighborhoodType.Removable;
                }
            }
            return(types);
        }
Esempio n. 2
0
        static bool IsWithinGapLimits(SkeletonMinutia end1, SkeletonMinutia end2)
        {
            int distanceSq = (end1.Position - end2.Position).LengthSq;

            if (distanceSq <= Integers.Sq(Parameters.MaxRuptureSize))
            {
                return(true);
            }
            if (distanceSq > Integers.Sq(Parameters.MaxGapSize))
            {
                return(false);
            }
            double gapDirection = DoubleAngle.Atan(end1.Position, end2.Position);
            double direction1   = DoubleAngle.Atan(end1.Position, AngleSampleForGapRemoval(end1));

            if (DoubleAngle.Distance(direction1, DoubleAngle.Opposite(gapDirection)) > Parameters.MaxGapAngle)
            {
                return(false);
            }
            double direction2 = DoubleAngle.Atan(end2.Position, AngleSampleForGapRemoval(end2));

            if (DoubleAngle.Distance(direction2, gapDirection) > Parameters.MaxGapAngle)
            {
                return(false);
            }
            return(true);
        }
Esempio n. 3
0
 public BlockMap(int width, int height, int maxBlockSize)
 {
     Pixels  = new IntPoint(width, height);
     Primary = new BlockGrid(new IntPoint(
                                 Integers.RoundUpDiv(Pixels.X, maxBlockSize),
                                 Integers.RoundUpDiv(Pixels.Y, maxBlockSize)));
     for (int y = 0; y <= Primary.Blocks.Y; ++y)
     {
         Primary.Y[y] = y * Pixels.Y / Primary.Blocks.Y;
     }
     for (int x = 0; x <= Primary.Blocks.X; ++x)
     {
         Primary.X[x] = x * Pixels.X / Primary.Blocks.X;
     }
     Secondary      = new BlockGrid(Primary.Corners);
     Secondary.Y[0] = 0;
     for (int y = 0; y < Primary.Blocks.Y; ++y)
     {
         Secondary.Y[y + 1] = Primary.Block(0, y).Center.Y;
     }
     Secondary.Y[Secondary.Blocks.Y] = Pixels.Y;
     Secondary.X[0] = 0;
     for (int x = 0; x < Primary.Blocks.X; ++x)
     {
         Secondary.X[x + 1] = Primary.Block(x, 0).Center.X;
     }
     Secondary.X[Secondary.Blocks.X] = Pixels.X;
 }
Esempio n. 4
0
        public EdgeShape(ImmutableMinutia reference, ImmutableMinutia neighbor)
        {
            IntPoint vector   = neighbor.Position - reference.Position;
            double   quadrant = 0;
            int      x        = vector.X;
            int      y        = vector.Y;

            if (y < 0)
            {
                x        = -x;
                y        = -y;
                quadrant = Math.PI;
            }
            if (x < 0)
            {
                int tmp = -x;
                x         = y;
                y         = tmp;
                quadrant += DoubleAngle.HalfPi;
            }
            int shift  = 32 - (int)Integers.LeadingZeros(((uint)x | (uint)y) >> PolarCacheBits);
            int offset = (y >> shift) * PolarCacheRadius + (x >> shift);

            Length = PolarDistanceCache[offset] << shift;
            double angle = PolarAngleCache[offset] + quadrant;

            ReferenceAngle = DoubleAngle.Difference(reference.Direction, angle);
            NeighborAngle  = DoubleAngle.Difference(neighbor.Direction, DoubleAngle.Opposite(angle));
        }
Esempio n. 5
0
        static void RemoveMinutiaClouds(List <MutableMinutia> minutiae)
        {
            var radiusSq = Integers.Sq(Parameters.MinutiaCloudRadius);
            var removed  = new HashSet <MutableMinutia>(minutiae.Where(minutia => Parameters.MaxCloudSize < minutiae.Where(neighbor => (neighbor.Position - minutia.Position).LengthSq <= radiusSq).Count() - 1));

            minutiae.RemoveAll(minutia => removed.Contains(minutia));
        }
Esempio n. 6
0
        static BooleanMatrix Vote(BooleanMatrix input, BooleanMatrix mask, int radius, double majority, int borderDistance)
        {
            var size = input.Size;
            var rect = new IntRect(borderDistance, borderDistance, size.X - 2 * borderDistance, size.Y - 2 * borderDistance);

            int[] thresholds = new int[Integers.Sq(2 * radius + 1) + 1];
            for (int i = 0; i < thresholds.Length; ++i)
            {
                thresholds[i] = (int)Math.Ceiling(majority * i);
            }
            var counts = new IntMatrix(size);
            var output = new BooleanMatrix(size);

            for (int y = rect.Top; y < rect.Bottom; ++y)
            {
                int superTop    = y - radius - 1;
                int superBottom = y + radius;
                int yMin        = Math.Max(0, y - radius);
                int yMax        = Math.Min(size.Y - 1, y + radius);
                int yRange      = yMax - yMin + 1;
                for (int x = rect.Left; x < rect.Right; ++x)
                {
                    if (mask == null || mask[x, y])
                    {
                        int left     = x > 0 ? counts[x - 1, y] : 0;
                        int top      = y > 0 ? counts[x, y - 1] : 0;
                        int diagonal = x > 0 && y > 0 ? counts[x - 1, y - 1] : 0;
                        int xMin     = Math.Max(0, x - radius);
                        int xMax     = Math.Min(size.X - 1, x + radius);
                        int ones;
                        if (left > 0 && top > 0 && diagonal > 0)
                        {
                            ones = top + left - diagonal - 1;
                            int superLeft  = x - radius - 1;
                            int superRight = x + radius;
                            if (superLeft >= 0 && superTop >= 0 && input[superLeft, superTop])
                            {
                                ++ones;
                            }
                            if (superLeft >= 0 && superBottom < size.Y && input[superLeft, superBottom])
                            {
                                --ones;
                            }
                            if (superRight < size.X && superTop >= 0 && input[superRight, superTop])
                            {
                                --ones;
                            }
                            if (superRight < size.X && superBottom < size.Y && input[superRight, superBottom])
                            {
                                ++ones;
                            }
                        }
                        else
                        {
                            ones = 0;
                            for (int ny = yMin; ny <= yMax; ++ny)
                            {
                                for (int nx = xMin; nx <= xMax; ++nx)
                                {
                                    if (input[nx, ny])
                                    {
                                        ++ones;
                                    }
                                }
                            }
                        }
                        counts[x, y] = ones + 1;
                        if (ones >= thresholds[yRange * (xMax - xMin + 1)])
                        {
                            output[x, y] = true;
                        }
                    }
                }
            }
            return(output);
        }