PointF[,] Smooth(PointF[,] orientation, BinaryMap mask) { PointF[,] smoothed = new PointF[mask.Height, mask.Width]; Parallel.For(0, mask.Height, delegate(int y) { for (int x = 0; x < mask.Width; ++x) { if (mask.GetBit(x, y)) { RectangleC neighbors = new RectangleC( new Point(Math.Max(0, x - SmoothingRadius), Math.Max(0, y - SmoothingRadius)), new Point(Math.Min(mask.Width, x + SmoothingRadius + 1), Math.Min(mask.Height, y + SmoothingRadius + 1))); PointF sum = new PointF(); for (int ny = neighbors.Bottom; ny < neighbors.Top; ++ny) { for (int nx = neighbors.Left; nx < neighbors.Right; ++nx) { if (mask.GetBit(nx, ny)) { sum = Calc.Add(sum, orientation[ny, nx]); } } } smoothed[y, x] = sum; } } }); return(smoothed); }
float[,] PerformEqualization(BlockMap blocks, byte[,] image, float[, ,] equalization, BinaryMap blockMask) { float[,] result = new float[blocks.PixelCount.Height, blocks.PixelCount.Width]; Parallel.ForEach(blocks.AllBlocks, delegate(Point block) { if (blockMask.GetBit(block)) { RectangleC area = blocks.BlockAreas[block]; for (int y = area.Bottom; y < area.Top; ++y) { for (int x = area.Left; x < area.Right; ++x) { byte pixel = image[y, x]; float bottomLeft = equalization[block.Y, block.X, pixel]; float bottomRight = equalization[block.Y, block.X + 1, pixel]; float topLeft = equalization[block.Y + 1, block.X, pixel]; float topRight = equalization[block.Y + 1, block.X + 1, pixel]; PointF fraction = area.GetFraction(new Point(x, y)); result[y, x] = Calc.Interpolate(topLeft, topRight, bottomLeft, bottomRight, fraction); } } } }); Logger.Log(result); return(result); }
public float[,] Smooth(float[,] input, byte[,] orientation, BinaryMap mask, BlockMap blocks) { Point[][] lines = Lines.Construct(); float[,] output = new float[input.GetLength(0), input.GetLength(1)]; Parallel.ForEach(blocks.AllBlocks, delegate(Point block) { if (mask.GetBit(block)) { Point[] line = lines[Angle.Quantize(Angle.Add(orientation[block.Y, block.X], AngleOffset), lines.Length)]; foreach (Point linePoint in line) { RectangleC target = blocks.BlockAreas[block]; RectangleC source = target.GetShifted(linePoint); source.Clip(new RectangleC(blocks.PixelCount)); target = source.GetShifted(Calc.Negate(linePoint)); for (int y = target.Bottom; y < target.Top; ++y) for (int x = target.Left; x < target.Right; ++x) output[y, x] += input[y + linePoint.Y, x + linePoint.X]; } RectangleC blockArea = blocks.BlockAreas[block]; for (int y = blockArea.Bottom; y < blockArea.Top; ++y) for (int x = blockArea.Left; x < blockArea.Right; ++x) output[y, x] *= 1f / line.Length; } }); Logger.Log(output); return output; }
Range GetMaskLineRange(BinaryMap mask, int y) { int first = -1; int last = -1; for (int x = 0; x < mask.Width; ++x) { if (mask.GetBit(x, y)) { last = x; if (first < 0) { first = x; } } } if (first >= 0) { return(new Range(first, last + 1)); } else { return(new Range()); } }
public BinaryMap Binarize(float[,] input, float[,] baseline, BinaryMap mask, BlockMap blocks) { BinaryMap binarized = new BinaryMap(input.GetLength(1), input.GetLength(0)); Parallel.For(0, blocks.AllBlocks.Height, delegate(int blockY) { for (int blockX = 0; blockX < blocks.AllBlocks.Width; ++blockX) { if (mask.GetBit(blockX, blockY)) { RectangleC rect = blocks.BlockAreas[blockY, blockX]; for (int y = rect.Bottom; y < rect.Top; ++y) { for (int x = rect.Left; x < rect.Right; ++x) { if (input[y, x] - baseline[y, x] > 0) { binarized.SetBitOne(x, y); } } } } } }); Logger.Log(binarized); return(binarized); }
bool IsOverlapping(Point[] line, BinaryMap shadow) { for (int i = ToleratedOverlapLength; i < line.Length - ToleratedOverlapLength; ++i) { if (shadow.GetBit(line[i])) { return(true); } } return(false); }
static bool IsFalseEnding(BinaryMap binary, Point ending) { foreach (Point relativeNeighbor in Neighborhood.CornerNeighbors) { Point neighbor = Calc.Add(ending, relativeNeighbor); if (binary.GetBit(neighbor)) { return(Calc.CountBits(binary.GetNeighborhood(neighbor)) > 2); } } return(false); }
byte[,] ToAngles(PointF[,] vectors, BinaryMap mask) { byte[,] angles = new byte[mask.Height, mask.Width]; Parallel.For(0, mask.Height, delegate(int y) { for (int x = 0; x < mask.Width; ++x) { if (mask.GetBit(x, y)) { angles[y, x] = Angle.ToByte(Angle.Atan(vectors[y, x])); } } }); return(angles); }
List <Point> FindMinutiae(BinaryMap binary) { List <Point> result = new List <Point>(); for (int y = 0; y < binary.Height; ++y) { for (int x = 0; x < binary.Width; ++x) { if (binary.GetBit(x, y) && IsMinutia[binary.GetNeighborhood(x, y)]) { result.Add(new Point(x, y)); } } } return(result); }
PointF[,] SumBlocks(PointF[,] orientation, BlockMap blocks, BinaryMap mask) { PointF[,] sums = new PointF[blocks.BlockCount.Height, blocks.BlockCount.Width]; Parallel.ForEach(blocks.AllBlocks, delegate(Point block) { if (mask.GetBit(block)) { PointF sum = new PointF(); RectangleC area = blocks.BlockAreas[block]; for (int y = area.Bottom; y < area.Top; ++y) { for (int x = area.Left; x < area.Right; ++x) { sum = Calc.Add(sum, orientation[y, x]); } } sums[block.Y, block.X] = sum; } }); return(sums); }
public BinaryMap Filter(BinaryMap input) { RectangleC rect = new RectangleC(new Point(BorderDistance, BorderDistance), new Size(input.Width - 2 * BorderDistance, input.Height - 2 * BorderDistance)); BinaryMap output = new BinaryMap(input.Size); Parallel.For(rect.RangeY.Begin, rect.RangeY.End, delegate(int y) { for (int x = rect.Left; x < rect.Right; ++x) { RectangleC neighborhood = new RectangleC( new Point(Math.Max(x - Radius, 0), Math.Max(y - Radius, 0)), new Point(Math.Min(x + Radius + 1, output.Width), Math.Min(y + Radius + 1, output.Height))); int ones = 0; for (int ny = neighborhood.Bottom; ny < neighborhood.Top; ++ny) { for (int nx = neighborhood.Left; nx < neighborhood.Right; ++nx) { if (input.GetBit(nx, ny)) { ++ones; } } } double voteWeight = 1.0 / neighborhood.TotalArea; if (ones * voteWeight >= Majority) { output.SetBitOne(x, y); } } }); Logger.Log(output); return(output); }
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); }
public BinaryMap Filter(BinaryMap input) { ////Testing Start //Count++; //var inFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "inputBinary" + Count + ".bin"); //var outFileDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "outputBinary" + Count + ".bin"); //var file = new FileStream(inFileDir, FileMode.CreateNew); //var binWrite = new BinaryWriter(file); //binWrite.Write(input.WordWidth); //Console.WriteLine(input.WordWidth); //binWrite.Write(input.Width); //Console.WriteLine(input.Width); //binWrite.Write(input.Height); //Console.WriteLine(input.Height); //foreach (var i in input.Map) //{ // binWrite.Write(i); // Console.WriteLine(i); //} //binWrite.Close(); //file.Close(); ////Testing Finish RectangleC rect = new RectangleC(new Point(BorderDistance, BorderDistance), new Size(input.Width - 2 * BorderDistance, input.Height - 2 * BorderDistance)); BinaryMap output = new BinaryMap(input.Size); Parallel.For(rect.RangeY.Begin, rect.RangeY.End, delegate(int y) { for (int x = rect.Left; x < rect.Right; ++x) { RectangleC neighborhood = new RectangleC( new Point(Math.Max(x - Radius, 0), Math.Max(y - Radius, 0)), new Point(Math.Min(x + Radius + 1, output.Width), Math.Min(y + Radius + 1, output.Height))); int ones = 0; for (int ny = neighborhood.Bottom; ny < neighborhood.Top; ++ny) { for (int nx = neighborhood.Left; nx < neighborhood.Right; ++nx) { if (input.GetBit(nx, ny)) { ++ones; } } } double voteWeight = 1.0 / neighborhood.TotalArea; if (ones * voteWeight >= Majority) { output.SetBitOne(x, y); } } }); Logger.Log(output); ////Testing //file = new FileStream(outFileDir, FileMode.CreateNew); //binWrite = new BinaryWriter(file); //binWrite.Write(output.WordWidth); //binWrite.Write(output.Width); //binWrite.Write(output.Height); //foreach (var i in output.Map) //{ // binWrite.Write(i); //} //binWrite.Close(); //file.Close(); ////Testing End return(output); }