private double[] GetOrientations(int radio, Minutia mtia, OrientationImage dirImg) { double[] currOrientations = new double[radio / 3]; int n = radio / 3; double incAng = 2 * Math.PI * 3.0 / radio; for (int i = 0; i < n; i++) { double myAng = mtia.Angle + i * incAng; if (myAng > 2 * Math.PI) { myAng -= (double)(2 * Math.PI); } Point pnt = SetPosToSPoint(myAng, radio, new Point(mtia.X, mtia.Y)); int row, col; dirImg.GetBlockCoordFromPixel(pnt.X, pnt.Y, out row, out col); if ((col < 0) || (row < 0) || (row >= dirImg.Height) || (col >= dirImg.Width) || (dirImg.IsNullBlock(row, col))) { currOrientations[i] = double.NaN; } else { currOrientations[i] = Math.Min(Angle.DifferencePi(mtia.Angle, dirImg.AngleInRadians(row, col)), Angle.DifferencePi(mtia.Angle, dirImg.AngleInRadians(row, col) + Math.PI)); } } return(currOrientations); }
private static double[] GetOrientations(int radio, Minutia mtia, OrientationImage dirImg) { var currOrientations = new double[radio / 3]; var n = radio / 3; var incAng = 2 * Math.PI * 3.0 / radio; for (var i = 0; i < n; i++) { var myAng = mtia.Angle + i * incAng; if (myAng > 2 * Math.PI) { myAng -= 2 * Math.PI; } var pnt = SetPosToSPoint(myAng, radio, new Point(mtia.X, mtia.Y)); dirImg.GetBlockCoordFromPixel(pnt.X, pnt.Y, out var row, out var col); if (col < 0 || row < 0 || row >= dirImg.Height || col >= dirImg.Width || dirImg.IsNullBlock(row, col)) { currOrientations[i] = double.NaN; } else { currOrientations[i] = Math.Min(Angle.DifferencePi(mtia.Angle, dirImg.AngleInRadians(row, col)), Angle.DifferencePi(mtia.Angle, dirImg.AngleInRadians(row, col) + Math.PI)); } } return(currOrientations); }
private int[] GetProjection(OrientationImage oi, int row, int col, int x, int y, ImageMatrix matrix) { double angle = oi.AngleInRadians(row, col); double orthogonalAngle = oi.AngleInRadians(row, col) + Math.PI / 2; int maxLength = oi.WindowSize / 2; int[] projection = new int[2 * maxLength + 1]; int[] outlayerCount = new int[2 * maxLength + 1]; bool outlayerFound = false; int totalSum = 0; int validPointsCount = 0; for (int li = -maxLength, i = 0; li <= maxLength; li++, i++) { int xi = Convert.ToInt32(x - li * Math.Cos(orthogonalAngle)); int yi = Convert.ToInt32(y - li * Math.Sin(orthogonalAngle)); int ySum = 0; for (int lj = -maxLength; lj <= maxLength; lj++) { int xj = Convert.ToInt32(xi - lj * Math.Cos(angle)); int yj = Convert.ToInt32(yi - lj * Math.Sin(angle)); if (xj >= 0 && yj >= 0 && xj < matrix.Width && yj < matrix.Height) { ySum += matrix[yj, xj]; validPointsCount++; } else { outlayerCount[i]++; outlayerFound = true; } } projection[i] = ySum; totalSum += ySum; } if (outlayerFound) { int avg = totalSum / validPointsCount; for (int i = 0; i < projection.Length; i++) { projection[i] += avg * outlayerCount[i]; } } return(projection); }
internal Segment(double ang, Minutia mnt, OrientationImage dImg) { bool endOfPoints = false; int i = 1; List <double> points = new List <double>(); while (!endOfPoints) { Point pnt = SetPosToSPoint(ang, i * interval, new Point(mnt.X, mnt.Y)); if (IsInBound(pnt, dImg)) { int row, col; dImg.GetBlockCoordFromPixel(pnt.X, pnt.Y, out row, out col); if ((col < 0) || (row < 0) || (row >= dImg.Height) || (col >= dImg.Width) || (dImg.IsNullBlock(row, col))) { points.Add(double.NaN); } else { points.Add(Math.Min(Angle.DifferencePi(mnt.Angle, dImg.AngleInRadians(row, col)), Angle.DifferencePi(mnt.Angle, dImg.AngleInRadians(row, col) + Math.PI))); } i++; } else { endOfPoints = true; } } bool isLastNan = false; int j = points.Count - 1; while (!isLastNan && j >= 0) { if (double.IsNaN(points[j])) { points.RemoveAt(j); j--; } else { isLastNan = true; } } directions = points.ToArray(); }
private static OrientationImage SmoothOrImg(OrientationImage img) { var smoothed = new OrientationImage(img.Width, img.Height, img.WindowSize); const byte wSize = 3; for (var row = 0; row < img.Height; row++) { for (var col = 0; col < img.Width; col++) { if (!img.IsNullBlock(row, col)) { int count; double ySum; var xSum = ySum = count = 0; double angle; for (var y = row - wSize / 2; y <= row + wSize / 2; y++) { for (var x = col - wSize / 2; x <= col + wSize / 2; x++) { if (y >= 0 && y < img.Height && x >= 0 && x < img.Width && !img.IsNullBlock(y, x)) { angle = img.AngleInRadians(y, x); xSum += Math.Cos(2 * angle); ySum += Math.Sin(2 * angle); count++; } } } if (count == 0 || Math.Abs(xSum) < double.Epsilon && Math.Abs(ySum) < double.Epsilon) { smoothed[row, col] = OrientationImage.Null; } else { var xAvg = xSum / count; var yAvg = ySum / count; angle = Angle.ToDegrees(Angle.ComputeAngle(xAvg, yAvg)) / 2; smoothed[row, col] = Convert.ToByte(Math.Round(angle)); } } else { smoothed[row, col] = OrientationImage.Null; } } } return(smoothed); }
private static void RemoveSpikes(ImageMatrix matrix, OrientationImage orientationImage) { for (var row = 0; row < orientationImage.Height; row++) { for (var col = 0; col < orientationImage.Width; col++) { if (!orientationImage.IsNullBlock(row, col)) { var cos = new double[3]; var sin = new double[3]; var orthogonalAngle = orientationImage.AngleInRadians(row, col) + Math.PI / 2; cos[0] = Math.Cos(orthogonalAngle); sin[0] = Math.Sin(orthogonalAngle); var orthogonalAngle1 = orthogonalAngle + Math.PI / 12; cos[1] = Math.Cos(orthogonalAngle1); sin[1] = Math.Sin(orthogonalAngle1); var orthogonalAngle2 = orthogonalAngle - Math.PI / 12; cos[2] = Math.Cos(orthogonalAngle2); sin[2] = Math.Sin(orthogonalAngle2); orientationImage.GetPixelCoordFromBlock(row, col, out int x, out int y); var maxLength = orientationImage.WindowSize / 2; for (var xi = x - maxLength; xi < x + maxLength; xi++) { for (var yi = y - maxLength; yi < y + maxLength; yi++) { var xj = xi; var yj = yi; var spikeFound = true; while (spikeFound) { spikeFound = false; if (xj > 0 && xj < matrix.Width - 1 && yj > 0 && yj < matrix.Height - 1) { var tl = matrix[yj - 1, xj - 1]; var tc = matrix[yj - 1, xj]; var tr = matrix[yj - 1, xj + 1]; var le = matrix[yj, xj - 1]; var ce = matrix[yj, xj]; var ri = matrix[yj, xj + 1]; var bl = matrix[yj + 1, xj - 1]; var bc = matrix[yj + 1, xj]; var br = matrix[yj + 1, xj + 1]; if (CouldBeSpike(tl, tc, tr, le, ce, ri, bl, bc, br)) { for (var i = 0; i < sin.Length && !spikeFound; i++) { var xk = Convert.ToInt32(Math.Round(xj - cos[i])); var yk = Convert.ToInt32(Math.Round(yj - sin[i])); if (matrix[yk, xk] == 0) { matrix[yj, xj] = 255; xj = xk; yj = yk; spikeFound = true; } else { xk = Convert.ToInt32(Math.Round(xj + cos[i])); yk = Convert.ToInt32(Math.Round(yj + sin[i])); if (matrix[yk, xk] == 0) { matrix[yj, xj] = 255; xj = xk; yj = yk; spikeFound = true; } } } } } } } } } } } }
private static List <Minutia> GetMinutiaes(ImageMatrix matrix, OrientationImage orientationImage) { var minutiaes = new List <Minutia>(); for (var row = 0; row < orientationImage.Height; row++) { for (var col = 0; col < orientationImage.Width; col++) { if (!orientationImage.IsNullBlock(row, col)) { orientationImage.GetPixelCoordFromBlock(row, col, out var x, out var y); var maxLength = orientationImage.WindowSize / 2; for (var xi = x - maxLength; xi < x + maxLength; xi++) { for (var yi = y - maxLength; yi < y + maxLength; yi++) { if (xi > 0 && xi < matrix.Width - 1 && yi > 0 && yi < matrix.Height - 1) { if (matrix[yi, xi] == 0) { var values = new List <int> { matrix[yi, xi + 1] == 255 ? 0 : 1, matrix[yi - 1, xi + 1] == 255 ? 0 : 1, matrix[yi - 1, xi] == 255 ? 0 : 1, matrix[yi - 1, xi - 1] == 255 ? 0 : 1, matrix[yi, xi - 1] == 255 ? 0 : 1, matrix[yi + 1, xi - 1] == 255 ? 0 : 1, matrix[yi + 1, xi] == 255 ? 0 : 1, matrix[yi + 1, xi + 1] == 255 ? 0 : 1 }; var cn = 0; for (var i = 0; i < values.Count; i++) { var idx = i; if (i == 7) { idx = -1; } cn += Math.Abs(values[i] - values[idx + 1]); } cn = (int)(cn * 0.5); double angleminu; // end minutiae if (cn == 1) { angleminu = GetMinutiaeAngle(matrix, xi, yi, MinutiaType.End); if (Math.Abs(angleminu - (-1)) > double.Epsilon) { minutiaes.Add(new Minutia { Angle = (float)angleminu, X = (short)xi, Y = (short)yi, MinutiaType = MinutiaType.End } ); } } //bifurcation minutiae if (cn == 3) { angleminu = GetMinutiaeAngle(matrix, xi, yi, MinutiaType.Bifurcation); if (!double.IsNaN(angleminu) && Math.Abs(angleminu - (-1)) > double.Epsilon) { minutiaes.Add(new Minutia { Angle = (float)angleminu, X = (short)xi, Y = (short)yi, MinutiaType = MinutiaType.Bifurcation } ); } } } } } } } } } var noInTheBorder = new List <Minutia>(); for (var i = 0; i < minutiaes.Count; i++) { // boundary Effects (foreground areas) orientationImage.GetBlockCoordFromPixel(minutiaes[i].X, minutiaes[i].Y, out var row, out var col); if (row >= 1 && col >= 1 && col < orientationImage.Width - 1 && row < orientationImage.Height - 1) { if (! (orientationImage.IsNullBlock(row - 1, col) || orientationImage.IsNullBlock(row + 1, col) || orientationImage.IsNullBlock(row, col - 1) || orientationImage.IsNullBlock(row, col + 1) //|| ) ) { noInTheBorder.Add(minutiaes[i]); } } } var toErase = new bool[noInTheBorder.Count]; for (var i = 0; i < noInTheBorder.Count; i++) { var mA = noInTheBorder[i]; for (var j = 0; j < noInTheBorder.Count; j++) { if (i != j) { var mB = noInTheBorder[j]; // different to orientation image orientationImage.GetBlockCoordFromPixel(mA.X, mA.Y, out var row, out var col); var angleOi = orientationImage.AngleInRadians(row, col); if (mA.MinutiaType == MinutiaType.End && Math.Min(Angle.DifferencePi(mA.Angle, angleOi), Angle.DifferencePi(mA.Angle, angleOi + Math.PI)) > Math.PI / 6) { toErase[i] = true; } // near minutiaes elimination if (mA.MinutiaType == mB.MinutiaType && MtiaEuclideanDistance.Compare(mA, mB) < 5) { toErase[i] = toErase[j] = true; } // Ridge break elimination (Ratha) if (mA.MinutiaType == MinutiaType.End && mB.MinutiaType == MinutiaType.End && Math.Abs(mA.Angle - mB.Angle) < double.Epsilon && MtiaEuclideanDistance.Compare(mA, mB) < 10) { toErase[i] = toErase[j] = true; } // Ridge break elimination (tavo - migue) if (mA.MinutiaType == MinutiaType.End && mB.MinutiaType == MinutiaType.End && Angle.DifferencePi(mA.Angle, mB.Angle) < Math.PI / 12 && MtiaEuclideanDistance.Compare(mA, mB) < 10) { toErase[i] = toErase[j] = true; } // spike elimination if (mA.MinutiaType == MinutiaType.End && mB.MinutiaType == MinutiaType.Bifurcation && MtiaEuclideanDistance.Compare(mA, mB) < 15) { if (RemoveSpikeOnMinutiae(matrix, mA, mB)) { toErase[i] = true; } } } } } var result = new List <Minutia>(); for (var i = 0; i < noInTheBorder.Count; i++) { if (!toErase[i]) { result.Add(noInTheBorder[i]); } } return(result); }