Пример #1
0
        static BooleanMatrix Mask(BlockMap blocks, HistogramCube histogram)
        {
            var contrast = ClipContrast(blocks, histogram);
            var mask     = FilterAbsoluteContrast(contrast);

            mask.Merge(FilterRelativeContrast(contrast, blocks));
            // https://sourceafis.machinezoo.com/transparency/combined-mask
            FingerprintTransparency.Current.Log("combined-mask", mask);
            mask.Merge(FilterBlockErrors(mask));
            mask.Invert();
            mask.Merge(FilterBlockErrors(mask));
            mask.Merge(FilterBlockErrors(mask));
            mask.Merge(Vote(mask, null, Parameters.MaskVoteRadius, Parameters.MaskVoteMajority, Parameters.MaskVoteBorderDistance));
            // https://sourceafis.machinezoo.com/transparency/filtered-mask
            FingerprintTransparency.Current.Log("filtered-mask", mask);
            return(mask);
        }
Пример #2
0
        static HistogramCube Histogram(BlockMap blocks, DoubleMatrix image)
        {
            var histogram = new HistogramCube(blocks.Primary.Blocks, Parameters.HistogramDepth);

            foreach (var block in blocks.Primary.Blocks.Iterate())
            {
                var area = blocks.Primary.Block(block);
                for (int y = area.Top; y < area.Bottom; ++y)
                {
                    for (int x = area.Left; x < area.Right; ++x)
                    {
                        int depth = (int)(image[x, y] * histogram.Bins);
                        histogram.Increment(block, histogram.Constrain(depth));
                    }
                }
            }
            // https://sourceafis.machinezoo.com/transparency/histogram
            FingerprintTransparency.Current.Log("histogram", histogram);
            return(histogram);
        }
Пример #3
0
        static HistogramCube SmoothHistogram(BlockMap blocks, HistogramCube input)
        {
            var blocksAround = new IntPoint[] { new IntPoint(0, 0), new IntPoint(-1, 0), new IntPoint(0, -1), new IntPoint(-1, -1) };
            var output       = new HistogramCube(blocks.Secondary.Blocks, input.Bins);

            foreach (var corner in blocks.Secondary.Blocks.Iterate())
            {
                foreach (var relative in blocksAround)
                {
                    var block = corner + relative;
                    if (blocks.Primary.Blocks.Contains(block))
                    {
                        for (int i = 0; i < input.Bins; ++i)
                        {
                            output.Add(corner, i, input[block, i]);
                        }
                    }
                }
            }
            // https://sourceafis.machinezoo.com/transparency/smoothed-histogram
            FingerprintTransparency.Current.Log("smoothed-histogram", output);
            return(output);
        }
Пример #4
0
        static DoubleMatrix ClipContrast(BlockMap blocks, HistogramCube histogram)
        {
            var result = new DoubleMatrix(blocks.Primary.Blocks);

            foreach (var block in blocks.Primary.Blocks.Iterate())
            {
                int volume      = histogram.Sum(block);
                int clipLimit   = Doubles.RoundToInt(volume * Parameters.ClippedContrast);
                int accumulator = 0;
                int lowerBound  = histogram.Bins - 1;
                for (int i = 0; i < histogram.Bins; ++i)
                {
                    accumulator += histogram[block, i];
                    if (accumulator > clipLimit)
                    {
                        lowerBound = i;
                        break;
                    }
                }
                accumulator = 0;
                int upperBound = 0;
                for (int i = histogram.Bins - 1; i >= 0; --i)
                {
                    accumulator += histogram[block, i];
                    if (accumulator > clipLimit)
                    {
                        upperBound = i;
                        break;
                    }
                }
                result[block] = (upperBound - lowerBound) * (1.0 / (histogram.Bins - 1));
            }
            // https://sourceafis.machinezoo.com/transparency/contrast
            FingerprintTransparency.Current.Log("contrast", result);
            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);
        }