예제 #1
0
 static void MaskMinutiae(List <MutableMinutia> minutiae, BooleanMatrix mask)
 {
     minutiae.RemoveAll(minutia =>
     {
         var arrow = (-Parameters.MaskDisplacement * DoubleAngle.ToVector(minutia.Direction)).Round();
         return(!mask.Get(minutia.Position + arrow, false));
     });
 }
예제 #2
0
        static void TraceRidges(BooleanMatrix thinned, Dictionary <IntPoint, SkeletonMinutia> minutiaePoints)
        {
            var leads = new Dictionary <IntPoint, SkeletonRidge>();

            foreach (var minutiaPoint in minutiaePoints.Keys)
            {
                foreach (var startRelative in IntPoint.CornerNeighbors)
                {
                    var start = minutiaPoint + startRelative;
                    if (thinned.Get(start, false) && !minutiaePoints.ContainsKey(start) && !leads.ContainsKey(start))
                    {
                        var ridge = new SkeletonRidge();
                        ridge.Points.Add(minutiaPoint);
                        ridge.Points.Add(start);
                        var previous = minutiaPoint;
                        var current  = start;
                        do
                        {
                            var next = IntPoint.Zero;
                            foreach (var nextRelative in IntPoint.CornerNeighbors)
                            {
                                next = current + nextRelative;
                                if (thinned.Get(next, false) && next != previous)
                                {
                                    break;
                                }
                            }
                            previous = current;
                            current  = next;
                            ridge.Points.Add(current);
                        } while (!minutiaePoints.ContainsKey(current));
                        var end = current;
                        ridge.Start                     = minutiaePoints[minutiaPoint];
                        ridge.End                       = minutiaePoints[end];
                        leads[ridge.Points[1]]          = ridge;
                        leads[ridge.Reversed.Points[1]] = ridge;
                    }
                }
            }
        }
예제 #3
0
 static bool IsFalseEnding(BooleanMatrix binary, IntPoint ending)
 {
     foreach (var relativeNeighbor in IntPoint.CornerNeighbors)
     {
         var neighbor = ending + relativeNeighbor;
         if (binary[neighbor])
         {
             int count = 0;
             foreach (var relative2 in IntPoint.CornerNeighbors)
             {
                 if (binary.Get(neighbor + relative2, false))
                 {
                     ++count;
                 }
             }
             return(count > 2);
         }
     }
     return(false);
 }
예제 #4
0
        List <IntPoint> FindMinutiae(BooleanMatrix thinned)
        {
            var result = new List <IntPoint>();

            foreach (var at in Size.Iterate())
            {
                if (thinned[at])
                {
                    int count = 0;
                    foreach (var relative in IntPoint.CornerNeighbors)
                    {
                        if (thinned.Get(at + relative, false))
                        {
                            ++count;
                        }
                    }
                    if (count == 1 || count > 2)
                    {
                        result.Add(at);
                    }
                }
            }
            return(result);
        }
예제 #5
0
        static DoubleMatrix Equalize(BlockMap blocks, DoubleMatrix image, HistogramCube histogram, BooleanMatrix blockMask)
        {
            const double rangeMin    = -1;
            const double rangeMax    = 1;
            const double rangeSize   = rangeMax - rangeMin;
            double       widthMax    = rangeSize / histogram.Bins * Parameters.MaxEqualizationScaling;
            double       widthMin    = rangeSize / histogram.Bins * Parameters.MinEqualizationScaling;
            var          limitedMin  = new double[histogram.Bins];
            var          limitedMax  = new double[histogram.Bins];
            var          dequantized = new double[histogram.Bins];

            for (int i = 0; i < histogram.Bins; ++i)
            {
                limitedMin[i]  = Math.Max(i * widthMin + rangeMin, rangeMax - (histogram.Bins - 1 - i) * widthMax);
                limitedMax[i]  = Math.Min(i * widthMax + rangeMin, rangeMax - (histogram.Bins - 1 - i) * widthMin);
                dequantized[i] = i / (double)(histogram.Bins - 1);
            }
            var mappings = new Dictionary <IntPoint, double[]>();

            foreach (var corner in blocks.Secondary.Blocks.Iterate())
            {
                double[] mapping = new double[histogram.Bins];
                mappings[corner] = mapping;
                if (blockMask.Get(corner, false) ||
                    blockMask.Get(corner.X - 1, corner.Y, false) ||
                    blockMask.Get(corner.X, corner.Y - 1, false) ||
                    blockMask.Get(corner.X - 1, corner.Y - 1, false))
                {
                    double step = rangeSize / histogram.Sum(corner);
                    double top  = rangeMin;
                    for (int i = 0; i < histogram.Bins; ++i)
                    {
                        double band      = histogram[corner, i] * step;
                        double equalized = top + dequantized[i] * band;
                        top += band;
                        if (equalized < limitedMin[i])
                        {
                            equalized = limitedMin[i];
                        }
                        if (equalized > limitedMax[i])
                        {
                            equalized = limitedMax[i];
                        }
                        mapping[i] = equalized;
                    }
                }
            }
            var result = new DoubleMatrix(blocks.Pixels);

            foreach (var block in blocks.Primary.Blocks.Iterate())
            {
                var area = blocks.Primary.Block(block);
                if (blockMask[block])
                {
                    var topleft     = mappings[block];
                    var topright    = mappings[new IntPoint(block.X + 1, block.Y)];
                    var bottomleft  = mappings[new IntPoint(block.X, block.Y + 1)];
                    var bottomright = mappings[new IntPoint(block.X + 1, block.Y + 1)];
                    for (int y = area.Top; y < area.Bottom; ++y)
                    {
                        for (int x = area.Left; x < area.Right; ++x)
                        {
                            int    depth = histogram.Constrain((int)(image[x, y] * histogram.Bins));
                            double rx    = (x - area.X + 0.5) / area.Width;
                            double ry    = (y - area.Y + 0.5) / area.Height;
                            result[x, y] = Doubles.Interpolate(bottomleft[depth], bottomright[depth], topleft[depth], topright[depth], rx, ry);
                        }
                    }
                }
                else
                {
                    for (int y = area.Top; y < area.Bottom; ++y)
                    {
                        for (int x = area.Left; x < area.Right; ++x)
                        {
                            result[x, y] = -1;
                        }
                    }
                }
            }
            // https://sourceafis.machinezoo.com/transparency/equalized-image
            FingerprintTransparency.Current.Log("equalized-image", result);
            return(result);
        }