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); }
BinaryMap Subtract(BinaryMap outer, BinaryMap inner) { BinaryMap buffer = new BinaryMap(outer); buffer.AndNot(inner); return(buffer); }
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); }
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); }
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); }
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); }