示例#1
0
        public void Remove(BinaryMap input)
        {
            BinaryMap sw2ne     = new BinaryMap(input.Size);
            BinaryMap se2nw     = new BinaryMap(input.Size);
            BinaryMap positions = new BinaryMap(input.Size);
            BinaryMap squares   = new BinaryMap(input.Size);

            while (true)
            {
                sw2ne.Copy(input, new RectangleC(0, 0, input.Width - 1, input.Height - 1), new Point());
                sw2ne.And(input, new RectangleC(1, 1, input.Width - 1, input.Height - 1), new Point());
                sw2ne.AndNot(input, new RectangleC(0, 1, input.Width - 1, input.Height - 1), new Point());
                sw2ne.AndNot(input, new RectangleC(1, 0, input.Width - 1, input.Height - 1), new Point());

                se2nw.Copy(input, new RectangleC(0, 1, input.Width - 1, input.Height - 1), new Point());
                se2nw.And(input, new RectangleC(1, 0, input.Width - 1, input.Height - 1), new Point());
                se2nw.AndNot(input, new RectangleC(0, 0, input.Width - 1, input.Height - 1), new Point());
                se2nw.AndNot(input, new RectangleC(1, 1, input.Width - 1, input.Height - 1), new Point());

                positions.Copy(sw2ne);
                positions.Or(se2nw);
                if (positions.IsEmpty())
                {
                    break;
                }

                squares.Copy(positions);
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(1, 0));
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(0, 1));
                squares.Or(positions, new RectangleC(0, 0, positions.Width - 1, positions.Height - 1), new Point(1, 1));

                input.AndNot(squares);
            }
            Logger.Log(input);
        }
示例#2
0
        BinaryMap Subtract(BinaryMap outer, BinaryMap inner)
        {
            BinaryMap buffer = new BinaryMap(outer);

            buffer.AndNot(inner);
            return(buffer);
        }
示例#3
0
        public TemplateBuilder Extract(byte[,] invertedImage, int dpi)
        {
            TemplateBuilder template = null;

            DpiAdjuster.Adjust(this, dpi, delegate()
            {
                byte[,] image = ImageInverter.GetInverted(invertedImage);

                BlockMap blocks = new BlockMap(new Size(image.GetLength(1), image.GetLength(0)), BlockSize);
                Logger.Log("BlockMap", blocks);

                short[, ,] histogram       = Histogram.Analyze(blocks, image);
                short[, ,] smoothHistogram = Histogram.SmoothAroundCorners(blocks, histogram);
                BinaryMap mask             = Mask.ComputeMask(blocks, histogram);
                float[,] equalized         = Equalizer.Equalize(blocks, image, smoothHistogram, mask);

                byte[,] orientation = Orientation.Detect(equalized, mask, blocks);
                float[,] smoothed   = RidgeSmoother.Smooth(equalized, orientation, mask, blocks);
                float[,] orthogonal = OrthogonalSmoother.Smooth(smoothed, orientation, mask, blocks);

                BinaryMap binary = Binarizer.Binarize(smoothed, orthogonal, mask, blocks);
                binary.AndNot(BinarySmoother.Filter(binary.GetInverted()));
                binary.Or(BinarySmoother.Filter(binary));
                Logger.Log("ResultadoSmoothingBinario", binary);
                CrossRemover.Remove(binary);

                BinaryMap pixelMask = mask.FillBlocks(blocks);
                BinaryMap innerMask = InnerMask.Compute(pixelMask);

                BinaryMap inverted = binary.GetInverted();
                inverted.And(pixelMask);

                SkeletonBuilder ridges  = null;
                SkeletonBuilder valleys = null;
                Parallel.Invoke(
                    () => { ridges = ProcessSkeleton("Ridges", binary); },
                    () => { valleys = ProcessSkeleton("Valleys", inverted); });

                template                = new TemplateBuilder();
                template.OriginalDpi    = dpi;
                template.OriginalWidth  = invertedImage.GetLength(1);
                template.OriginalHeight = invertedImage.GetLength(0);

                MinutiaCollector.Collect(ridges, TemplateBuilder.MinutiaType.Extremidade, template);
                MinutiaCollector.Collect(valleys, TemplateBuilder.MinutiaType.Bifurcação, template);
                MinutiaMask.Filter(template, innerMask);
                StandardDpiScaling.Scale(template);
                MinutiaCloudRemover.Filter(template);
                UniqueMinutiaSorter.Filter(template);
                MinutiaSorter.Shuffle(template);
                Logger.Log("FinalTemplate", template);
            });
            return(template);
        }
示例#4
0
        public TemplateBuilder Extract(byte[,] invertedImage, int dpi)
        {
            TemplateBuilder template = null;

            DpiAdjuster.Adjust(this, dpi, delegate()
            {
                byte[,] image = ImageInverter.GetInverted(invertedImage);  //图片反色,黑《--》白

                //var watch = Stopwatch.StartNew();
                //watch.Start();
                BlockMap blocks = new BlockMap(new Size(image.GetLength(1), image.GetLength(0)), BlockSize); //将图片数组转换为blockmap,对图片进行分块,方便进行并行计算
                Logger.Log("BlockMap", blocks);                                                              //可能是用于调试时的log输出
                //watch.Start();
                short[, ,] histogram = Histogram.Analyze(blocks, image);
                //watch.Stop();
                //Console.WriteLine("---------------------------histogram实例化时间:{0}",watch.ElapsedMilliseconds);
                //watch.Start();
                short[, ,] smoothHistogram = Histogram.SmoothAroundCorners(blocks, histogram);
                BinaryMap mask             = Mask.ComputeMask(blocks, histogram);
                float[,] equalized         = Equalizer.Equalize(blocks, image, smoothHistogram, mask);
                //watch.Stop();
                //Console.WriteLine("----------------------------equalized实例化时间:{0}",watch.ElapsedMilliseconds);
                byte[,] orientation = Orientation.Detect(equalized, mask, blocks);

                equalizedMap        = GdiIO.GetBitmap(ShowImage.floatToByte(equalized));
                float[,] smoothed   = RidgeSmoother.Smooth(equalized, orientation, mask, blocks);
                float[,] orthogonal = OrthogonalSmoother.Smooth(smoothed, orientation, mask, blocks);

                BinaryMap binary = Binarizer.Binarize(smoothed, orthogonal, mask, blocks);
                binary.AndNot(BinarySmoother.Filter(binary.GetInverted()));
                binary.Or(BinarySmoother.Filter(binary));
                Logger.Log("BinarySmoothingResult", binary);
                CrossRemover.Remove(binary);

                BinaryMap pixelMask = mask.FillBlocks(blocks);
                BinaryMap innerMask = InnerMask.Compute(pixelMask);

                BinaryMap inverted = binary.GetInverted();
                inverted.And(pixelMask);

                SkeletonBuilder ridges  = null;
                SkeletonBuilder valleys = null;
                Parallel.Invoke(
                    () => { ridges = ProcessSkeleton("Ridges", binary); },
                    () => { valleys = ProcessSkeleton("Valleys", inverted); });

                template                = new TemplateBuilder();
                template.OriginalDpi    = dpi;
                template.OriginalWidth  = invertedImage.GetLength(1);
                template.OriginalHeight = invertedImage.GetLength(0);

                MinutiaCollector.Collect(ridges, TemplateBuilder.MinutiaType.Ending, template);
                MinutiaCollector.Collect(valleys, TemplateBuilder.MinutiaType.Bifurcation, template);
                MinutiaMask.Filter(template, innerMask);
                StandardDpiScaling.Scale(template);
                MinutiaCloudRemover.Filter(template);
                UniqueMinutiaSorter.Filter(template);
                MinutiaSorter.Shuffle(template);
                Logger.Log("FinalTemplate", template);
                //watch.Stop();
                //Console.WriteLine("---------------------------Template实例化时间:{0}",watch.ElapsedMilliseconds);
            });
            return(template);
        }
示例#5
0
        public TemplateBuilder Extract(byte[,] invertedImage, int dpi)
        {
            TemplateBuilder template = null;

            DpiAdjuster.Adjust(this, dpi, delegate()
            {
                byte[,] image = ImageInverter.GetInverted(invertedImage);

                BlockMap blocks = new BlockMap(new Size(image.GetLength(1), image.GetLength(0)), BlockSize);
                Logger.Log("BlockMap", blocks);
                //Testing Start
                var outFileDir  = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "bloackMapOut" + DateTime.Now.Second + ".bin");
                var outFileText = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
                                               "blockMapTextOut" + DateTime.Now.Second + ".txt");
                var file      = new FileStream(outFileDir, FileMode.CreateNew);
                var binWrite  = new BinaryWriter(file);
                TextWriter tw = new StreamWriter(outFileText);
                LogSize(blocks.PixelCount, binWrite, tw, "PixelCount");
                LogSize(blocks.BlockCount, binWrite, tw, "BlockCount");
                LogSize(blocks.CornerCount, binWrite, tw, "CornerCount");
                LogRectangleC(blocks.AllBlocks, binWrite, tw, "AllBlocks");
                LogRectangleC(blocks.AllCorners, binWrite, tw, "AllCorners");
                LogPointGrid(blocks.Corners, binWrite, tw, "Corners");
                LogRectangleGrid(blocks.BlockAreas, binWrite, tw, "BlockAreas");
                LogPointGrid(blocks.BlockCenters, binWrite, tw, "BlockCenters");
                LogRectangleGrid(blocks.CornerAreas, binWrite, tw, "CornerAreas");
                binWrite.Close();
                tw.Close();
                //Testing End

                short[,,] histogram = Histogram.Analyze(blocks, image);
                ////testing
                //var outFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "histogramImageInput" + ".bin");
                //var file = new FileStream(outFileDir, FileMode.CreateNew);
                //var binWrite = new BinaryWriter(file);
                //binWrite.Write(image.GetLength(0));
                //binWrite.Write(image.GetLength(1));
                //for (var i = 0; i < image.GetLength(0); i++)
                //{
                //    for (var j = 0; j < image.GetLength(1); j++)
                //    {
                //        binWrite.Write(image[i, j]);
                //    }
                //}
                //binWrite.Close();
                ////End testing

                ////Testing Start
                //Count++;
                //var outFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "histogramOut" + Count + ".bin");
                //var outFileText = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
                //    "histogramTextOut" + Count + ".txt");
                //var file = new FileStream(outFileDir, FileMode.CreateNew);
                //var binWrite = new BinaryWriter(file);
                //TextWriter tw = new StreamWriter(outFileText);
                //binWrite.Write(histogram.GetLength(0));
                //tw.WriteLine(histogram.GetLength(0));
                //binWrite.Write(histogram.GetLength(1));
                //tw.WriteLine(histogram.GetLength(1));
                //binWrite.Write(histogram.GetLength(2));
                //tw.WriteLine(histogram.GetLength(2));
                //for (var i = 0; i < histogram.GetLength(0); i++)
                //{
                //    for (var j = 0; j < histogram.GetLength(1); j++)
                //    {
                //        for (var k = 0; k < histogram.GetLength(2); k++)
                //        {
                //            binWrite.Write(histogram[i, j, k]);
                //            tw.WriteLine(histogram[i, j, k]);
                //        }
                //    }
                //}
                //binWrite.Close();
                //file.Close();
                //tw.Close();
                //Testing Finish

                //Testing Start
                //outFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "bloackMapOutPostHis" + DateTime.Now.Second + ".bin");
                //outFileText = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
                //   "blockMapTextOutPostHis" + DateTime.Now.Second + ".txt");
                //file = new FileStream(outFileDir, FileMode.CreateNew);
                //binWrite = new BinaryWriter(file);
                //tw = new StreamWriter(outFileText);
                //LogSize(blocks.PixelCount, binWrite, tw);
                //LogSize(blocks.BlockCount, binWrite, tw);
                //LogSize(blocks.CornerCount, binWrite, tw);
                //LogRectangleC(blocks.AllBlocks, binWrite, tw);
                //LogRectangleC(blocks.AllCorners, binWrite, tw);
                //LogPointGrid(blocks.Corners, binWrite, tw);
                //LogRectangleGrid(blocks.BlockAreas, binWrite, tw);
                //LogPointGrid(blocks.BlockCenters, binWrite, tw);
                //LogRectangleGrid(blocks.CornerAreas, binWrite, tw);
                //binWrite.Close();
                //tw.Close();
                //Testing End

                short[,,] smoothHistogram = Histogram.SmoothAroundCorners(blocks, histogram);
                BinaryMap mask            = Mask.ComputeMask(blocks, histogram);
                float[,] equalized        = Equalizer.Equalize(blocks, image, smoothHistogram, mask);

                byte[,] orientation = Orientation.Detect(equalized, mask, blocks);
                float[,] smoothed   = RidgeSmoother.Smooth(equalized, orientation, mask, blocks);
                float[,] orthogonal = OrthogonalSmoother.Smooth(smoothed, orientation, mask, blocks);

                BinaryMap binary = Binarizer.Binarize(smoothed, orthogonal, mask, blocks);
                binary.AndNot(BinarySmoother.Filter(binary.GetInverted()));
                binary.Or(BinarySmoother.Filter(binary));
                Logger.Log("BinarySmoothingResult", binary);
                CrossRemover.Remove(binary);

                BinaryMap pixelMask = mask.FillBlocks(blocks);
                BinaryMap innerMask = InnerMask.Compute(pixelMask);

                BinaryMap inverted = binary.GetInverted();
                inverted.And(pixelMask);

                SkeletonBuilder ridges  = null;
                SkeletonBuilder valleys = null;

                Parallel.Invoke(
                    () => { ridges = ProcessSkeleton("Ridges", binary); },
                    () => { valleys = ProcessSkeleton("Valleys", inverted); });

                template                = new TemplateBuilder();
                template.OriginalDpi    = dpi;
                template.OriginalWidth  = invertedImage.GetLength(1);
                template.OriginalHeight = invertedImage.GetLength(0);

                MinutiaCollector.Collect(ridges, TemplateBuilder.MinutiaType.Ending, template);
                MinutiaCollector.Collect(valleys, TemplateBuilder.MinutiaType.Bifurcation, template);
                MinutiaMask.Filter(template, innerMask);
                StandardDpiScaling.Scale(template);
                MinutiaCloudRemover.Filter(template);
                UniqueMinutiaSorter.Filter(template);
                MinutiaSorter.Shuffle(template);
                Logger.Log("FinalTemplate", template);
            });
            return(template);
        }
示例#6
0
        public BinaryMap Thin(BinaryMap input)
        {
            BinaryMap intermediate = new BinaryMap(input.Size);

            intermediate.Copy(input, new RectangleC(1, 1, input.Width - 2, input.Height - 2), new Point(1, 1));

            BinaryMap border          = new BinaryMap(input.Size);
            BinaryMap skeleton        = new BinaryMap(input.Size);
            bool      removedAnything = true;

            for (int i = 0; i < MaxIterations && removedAnything; ++i)
            {
                removedAnything = false;
                for (int j = 0; j < 4; ++j)
                {
                    border.Copy(intermediate);
                    switch (j)
                    {
                    case 0:
                        border.AndNot(intermediate, new RectangleC(1, 0, border.Width - 1, border.Height), new Point(0, 0));
                        break;

                    case 1:
                        border.AndNot(intermediate, new RectangleC(0, 0, border.Width - 1, border.Height), new Point(1, 0));
                        break;

                    case 2:
                        border.AndNot(intermediate, new RectangleC(0, 1, border.Width, border.Height - 1), new Point(0, 0));
                        break;

                    case 3:
                        border.AndNot(intermediate, new RectangleC(0, 0, border.Width, border.Height - 1), new Point(0, 1));
                        break;
                    }
                    border.AndNot(skeleton);

                    for (int odd = 0; odd < 2; ++odd)
                    {
                        Parallel.For(1, input.Height - 1, delegate(int y)
                        {
                            if (y % 2 == odd)
                            {
                                for (int xw = 0; xw < input.WordWidth; ++xw)
                                {
                                    if (border.IsWordNonZero(xw, y))
                                    {
                                        for (int x = xw << BinaryMap.WordShift; x < (xw << BinaryMap.WordShift) + BinaryMap.WordSize; ++x)
                                        {
                                            if (x > 0 && x < input.Width - 1 && border.GetBit(x, y))
                                            {
                                                uint neighbors = intermediate.GetNeighborhood(x, y);
                                                if (IsRemovable[neighbors] ||
                                                    IsEnding[neighbors] && IsFalseEnding(intermediate, new Point(x, y)))
                                                {
                                                    removedAnything = true;
                                                    intermediate.SetBitZero(x, y);
                                                }
                                                else
                                                {
                                                    skeleton.SetBitOne(x, y);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        });
                    }
                }
            }

            Logger.Log(skeleton);
            return(skeleton);
        }