private Cylinder[] CreateCylinders(Minutia minutia) { Cylinder3D value = new Cylinder3D(); Cylinder3D mask = new Cylinder3D(); for (int i = 1; i <= BaseCuboid; i++) { for (int j = 1; j <= BaseCuboid; j++) { if (IsValidPoint(GetPoint(i, j, minutia), minutia)) { for (int k = 1; k <= HeightCuboid; k++) { mask.SetValue(i, j, k, 1); value.SetValue(i, j, k, StepFunction(Sum( GetPoint(i, j, minutia), AngleHeight(k), GetNeighborhood(GetPoint(i, j, minutia), minutia), minutia ) )); } } } } return new[] { new Cylinder(value.Cylinder, minutia.Angle, Math.Sqrt(CylinderHelper.GetOneBitsCount(value.Cylinder))), new Cylinder(mask.Cylinder, minutia.Angle, Math.Sqrt(CylinderHelper.GetOneBitsCount(mask.Cylinder))) }; }
private static double DetermineAngle(Minutia begin, Minutia end) { var dx = end.X - begin.X; var dy = begin.Y-end.Y; return Math.Atan2(dy, dx); }
public static List<Minutia> GetMinutias(int[,] data, PixelwiseOrientationField oField) { int width = data.GetLength(1); int height = data.GetLength(0); List<Minutia> minutias = new List<Minutia>(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (IsMinutia(data, x, y)) { Minutia m = new Minutia(); m.X = x; m.Y = y; m.Angle = (float) GetCorrectAngle( data, oField, x, y ); minutias.Add(m); } } } return minutias; }
private static double GetValue(Minutia currentMinutia, int k) { double result = 0; for (int counter = 0; counter < neighbourMinutiae.Count; counter++) { double spatialContribution = GetSpatialContribution(neighbourMinutiae[counter], currentСoordinate); double directionalContribution = GetDirectionalContribution(currentMinutia.Angle, neighbourMinutiae[counter].Angle, k); result += spatialContribution * directionalContribution; } return result; }
public static List<Minutia> FindMinutiae(double[,] picture) { List<Minutia> minutiae = new List<Minutia>(); double[,] area = new double[3, 3]; for (int k = 0; k < 3; k++) { for (int l = 0; l < 3; l++) { area[k, l] = 255; } } double[,] newPicture = new double[picture.GetLength(0) + 2, picture.GetLength(1) + 2]; for (int i = 0; i < newPicture.GetLength(0); i++) { for (int j = 0; j < newPicture.GetLength(1); j++) { newPicture[i, j] = 255; } } for (int i = 1; i < newPicture.GetLength(0) - 1; i++) { for (int j = 1; j < newPicture.GetLength(1) - 1; j++) { newPicture[i, j] = picture[i - 1, j - 1]; //Вставляем входную картинку в более широкий массив для удобства рассмотрения граничных случаев } } for (int i = 1; i < newPicture.GetLength(0) - 1; i++) { for (int j = 1; j < newPicture.GetLength(1) - 1; j++) { if (newPicture[i, j] == 0) { for (int k = 0; k < 3; k++) { for (int l = 0; l < 3; l++) { area[k, l] = newPicture[i - 1 + k, j - 1 + l]; //Проходим по массиву и проверяем для каждого черного пикселя, является ли он минуцией. } } if (CheckMinutiae(area) > 0) { Minutia newMinutiae = new Minutia(); //Если да, то добавляем минуцию в стек newMinutiae.X = j - 1; newMinutiae.Y = i - 1; minutiae.Add(newMinutiae); } } } } return minutiae; }
public void SimpleTestMcc() { List<Minutia> twoMinutiae = new List<Minutia>(); Minutia firstMinutia = new Minutia(); firstMinutia.X = 40; firstMinutia.Y = 60; firstMinutia.Angle = 0; twoMinutiae.Add(firstMinutia); Minutia secondMinutia = new Minutia(); secondMinutia.X = 70; secondMinutia.Y = 100; secondMinutia.Angle = Math.PI / 6; twoMinutiae.Add(secondMinutia); Dictionary<Minutia, Tuple<int[, ,], int[, ,]>> response = MCC.MCCMethod(twoMinutiae, 364, 256); SaveResponse(response, twoMinutiae); }
public static List<Minutia> LoadMinutiae(string filename) { var result = new List<Minutia>(); using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) { using (BinaryReader sr = new BinaryReader(fs)) { int i = sr.ReadInt32(); while(i-->0) { Minutia m = new Minutia(); m.X = sr.ReadInt32(); m.Y = sr.ReadInt32(); //m.Angle = sr.ReadDouble(); result.Add(m); } } } return result; }
internal static double TranslateAndMatch(List<Minutia> minutiae1, Minutia referenceMinutia1, List<Minutia> minutiae2, Minutia referenceMinutia2, double rotationAngle) { //from m1 to m2. I DEMAND IT var m1 = minutiae1.Select(x => new Minutia() { Angle = x.Angle, X = x.X - referenceMinutia1.X, Y = x.Y - referenceMinutia1.Y }).Reverse(); var m2 = minutiae2.Select(x => new Minutia() { Angle = x.Angle, X = x.X - referenceMinutia2.X, Y = x.Y - referenceMinutia2.Y }).Reverse().ToList(); var cos = Math.Cos(rotationAngle); var sin = -Math.Sin(rotationAngle); foreach (var m in m1) { var xDash = cos * m.X - sin * m.Y; var yDash = sin * m.X + cos * m.Y; if (m2.Any(x => (xDash - x.X) * (xDash - x.X) + (yDash - x.Y) * (yDash - x.Y) < MatchingToleranceBox * MatchingToleranceBox)) { m2.Remove(m2.OrderBy(x => (xDash - x.X) * (xDash - x.X) + (yDash - x.Y) * (yDash - x.Y)).First()); } } var total = (minutiae2.Count - m2.Count) ; return total; }
private double Sum(PointF point, double anglePoint, List<Minutia> neighborhood, Minutia middleMinutia) { double sum = 0; foreach (var minutia in neighborhood) { sum += GaussianLocation(minutia, point) * GaussianDirection(middleMinutia, minutia, anglePoint); } return sum; }
private bool IsValidPoint(PointF point, Minutia middleMinutia) { return VectorHelper.PointDistance(new PointF(middleMinutia.X, middleMinutia.Y), point) < Radius && FieldFiller.IsPointInsideHull(point, _convexHull); }
private PointF GetPoint(int i, int j, Minutia minutia) { return new PointF( (float) (minutia.X + BaseCell * (Math.Cos(minutia.Angle) * (i - (BaseCuboid + 1) / 2.0f) + Math.Sin(minutia.Angle) * (j - (BaseCuboid + 1) / 2.0f))), (float) (minutia.Y + BaseCell * (-Math.Sin(minutia.Angle) * (i - (BaseCuboid + 1) / 2.0f) + Math.Cos(minutia.Angle) * (j - (BaseCuboid + 1) / 2.0f))) ); }
private List<Minutia> GetNeighborhood(PointF point, Minutia middleMinutia) { List<Minutia> neighborhood = new List<Minutia>(); foreach (var minutia in _minutiaeList) { if (VectorHelper.PointDistance(new PointF(minutia.X, minutia.Y), point) < 3 * SigmaLocation && !EqualsMinutae(minutia, middleMinutia)) { neighborhood.Add(minutia); } } return neighborhood; }
public static extern void createTemplate(Minutia[] minutiae, int minutiaeLenght, out Cylinder[] cylinders, out int cylinderLenght);
static void Main(string[] args) { int countmax = 0; int countmin = 0; int max = 0; int min = 100; /*for (int i = 1; i <= 110; i++) { for (int j = 1; j <= 7; j += 4) { double[,] imgDoubles = ImageHelper.LoadImage<double>("d://DB2_bmp//" + i + "_" + j + ".bmp"); double[,] a = CreatTemplateTest(imgDoubles); int[,] bytes = Thinner.Thin(a, a.GetLength(1), a.GetLength(0)).Select2D(x => (int)x); PixelwiseOrientationField field = new PixelwiseOrientationField(bytes, 16); List<Minutia> minutias = MinutiaDetector.GetMinutias(bytes, field); foreach (var minutia in minutias) { Console.WriteLine(minutia.X + ", " + minutia.Y + ", " + minutia.Angle + ", "); } Console.WriteLine(); TemplateCreator creator = new TemplateCreator(minutias); Template[] t = { creator.CreateTemplate() }; foreach (var template in t) { for (int k = 0; k < template.Cylinders.Length; k+=2) { PrintCylinder(template.Cylinders[k].Values, template.Cylinders[k + 1].Values); } } if (BinTemplateSimilarity.GetTemplateSimilarity(t[0], t)[0].Equals(1)) { min = min > t[0].Cylinders.Count() ? t[0].Cylinders.Count() : min; countmin++; } else { countmax++; max = max < t[0].Cylinders.Count() ? t[0].Cylinders.Count() : max; } } }*/ /*double[,] imgDoubles = ImageHelper.LoadImage<double>("d://DB2_bmp//DB2_bmp//1_1.bmp"); double[,] a = CreatTemplateTest(imgDoubles); int[,] bytes = Thinner.Thin(a, a.GetLength(1), a.GetLength(0)).Select2D(x => (int)x); PixelwiseOrientationField field = new PixelwiseOrientationField(bytes, 16); List<Minutia> minutias = MinutiaDetector.GetMinutias(bytes, field); Console.WriteLine(minutias.Count);*/ Minutia minutia = new Minutia(); List<Minutia> minutiae = new List<Minutia>(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { minutia.X = i+11; minutia.Y = j+11; minutia.Angle = (float) (i); minutiae.Add(minutia); } } TemplateCreator creator = new TemplateCreator(minutiae); Template[] t = { creator.CreateTemplate() }; Console.WriteLine(t[0].Cylinders.Length); Console.ReadKey(); /* int count = 1; foreach (var template in t) { for (int k = 0; k < template.Cylinders.Length; k += 2) { PrintCylinder(template.Cylinders[k].Values, template.Cylinders[k + 1].Values, count); count++; } }*/ /* Console.WriteLine("min count fot 1 - {0} ({1})", min, countmin); Console.WriteLine("max count for < 1 - {0} ({1})", max, countmax);*/ // ImageHelper.SaveArrayToBitmap(CreatTemplateTest(a)).Save("d://hglf23.bmp"); /* imgDoubles = ImageHelper.LoadImage<double>("d://DB2_bmp//DB2_bmp//3_4.bmp"); a = CreatTemplateTest(imgDoubles); bytes = Thinner.Thin(a, a.GetLength(1), a.GetLength(0)).Select2D(x => (int)x); field = new PixelwiseOrientationField(bytes, 16); List<Minutia> minutiae2 = MinutiaDetector.GetMinutias(bytes, field); TemplateCreator creator2 = new TemplateCreator(minutiae2);*/ Console.ReadKey(); // seg.SaveSegmentation(seg.MakeBitmap(seg.Segmentate()),"d://123.bmp"); }
private static double DetermineDistance(Minutia m1, Minutia m2) { return Math.Sqrt((m1.X - m2.X) * (m1.X - m2.X) + (m1.Y - m2.Y) * (m1.Y - m2.Y)); }
private static double GetSpatialContribution(Minutia m, Tuple<int, int> currentCell) { double distance = GetDistance(m.X, m.Y, currentCell.Item1, currentCell.Item2); return Gaussian.Gaussian1D(distance, Constants.SigmaS); }
public void SimpleTestNumerationMcc() { List<Minutia> twoMinutiae = new List<Minutia>(); Minutia firstMinutia = new Minutia(); firstMinutia.X = 40; firstMinutia.Y = 60; firstMinutia.Angle = 0; twoMinutiae.Add(firstMinutia); Minutia secondMinutia = new Minutia(); secondMinutia.X = 70; secondMinutia.Y = 100; secondMinutia.Angle = Math.PI / 6; twoMinutiae.Add(secondMinutia); Dictionary<Minutia, Tuple<int[, ,], int[, ,]>> response = MCC.MCCMethod(twoMinutiae, 364, 256); for (int i = 0; i < response.Count; i++) { int[] valueN = Numeration.numerizationBlock(response[twoMinutiae[i]].Item1); int[] maskN = Numeration.numerizationBlock(response[twoMinutiae[i]].Item2); for (int j = 0; j < maskN.GetLength(0); j++) { //System.Console.Write(valueN[j] + " "); BitArray b = new BitArray(new int[] { maskN[j] }); bool[] bits = new bool[b.Count]; b.CopyTo(bits, 0); if (j % (maskN.Count() / 6) == 0) { // System.Console.Write(" j = " + j + "\n"); } for (int k = 0; k < bits.GetLength(0); k++) { System.Console.Write(bits[k]? 1 : 0); if (k == 15) { System.Console.Write(" i = "+i+"\n"); } } System.Console.Write(" j = "+j+"\n"); } System.Console.WriteLine(); System.Console.WriteLine(); for (int j = 0; j < valueN.GetLength(0); j++) { //System.Console.Write(valueN[j] + " "); BitArray b = new BitArray(new int[] { valueN[j] }); bool[] bits = new bool[b.Count]; b.CopyTo(bits, 0); if (j % (valueN.Count() / 6) == 0) { // System.Console.Write(" j = " + j + "\n"); } for (int k = 0; k < bits.GetLength(0); k++) { System.Console.Write(bits[k]? 1 : 0); if (k == 15) { System.Console.Write(" i = "+i+"\n"); } } System.Console.Write(" j = "+j+"\n"); } System.Console.WriteLine(); System.Console.WriteLine(); System.Console.WriteLine(); System.Console.WriteLine(); } }
private static List<Minutia> GetNeighbourMinutiae(List<Minutia> minutiae, Minutia minutia, Tuple<int, int> currentCell) { List<Minutia> result = new List<Minutia>(); for (int i = 0; i < minutiae.Count; i++) { if (minutiae[i] != minutia && GetDistance(minutiae[i].X, minutiae[i].Y, currentCell.Item1, currentCell.Item2) <= 3 * Constants.SigmaS) { result.Add(minutiae[i]); } } return result; }
private bool EqualsMinutae(Minutia firstMinutia, Minutia secondMinutia) { return ( firstMinutia.X == secondMinutia.X && firstMinutia.Y == secondMinutia.Y && Math.Abs(firstMinutia.Angle - secondMinutia.Angle) < float.Epsilon ); }
private static int CalculateMaskValue(Minutia m, int i, int j, int rows, int columns) { Tuple<int, int> point = GetCoordinatesInFingerprint(m, i, j); if (point.Item1 < 0 || point.Item1 >= rows || point.Item2 < 0 || point.Item2 >= columns) { return 0; } return ((GetDistance(m.X, m.Y, point.Item1, point.Item2) <= Constants.R) && workingArea[point.Item1, point.Item2]) ? 1 : 0; }
private double GaussianDirection(Minutia middleMinutia, Minutia minutia, double anglePoint) { double common = Math.Sqrt(2) * SigmaDirection; double angle = CylinderHelper.GetAngleDiff(anglePoint, CylinderHelper.GetAngleDiff(middleMinutia.Angle, minutia.Angle)); double first = Erf(((angle + HeightCell / 2)) / common); double second = Erf(((angle - HeightCell / 2)) / common); return (first - second) / 2; }
private static Tuple<int, int> GetCoordinatesInFingerprint(Minutia m, int i, int j) { double halfNs = (1 + Constants.Ns) / 2; double sinTetta = Math.Sin(m.Angle); double cosTetta = Math.Cos(m.Angle); double iDelta = cosTetta * (i - halfNs) + sinTetta * (j - halfNs); double jDelta = -sinTetta * (i - halfNs) + cosTetta * (j - halfNs); return new Tuple<int, int>((int)(m.X + deltaS * iDelta), (int)(m.Y + deltaS * jDelta)); }
private double GaussianLocation(Minutia minutia, PointF point) { return Gaussian.Gaussian1D(VectorHelper.PointDistance(new PointF(minutia.X, minutia.Y), point), SigmaLocation); }
public static List<Minutia> FindBigMinutiae(List<Minutia> source) { int Radius = 5; // this structure is used for storing indices for minutiae // that are closed to the minutia of the selected index // key of the pair is the minutia index that is the center of the circle var listBigMinutiae = new List<KeyValuePair<int, List<int>>>(); for (int i = 0; i < source.Count; i++) { List<int> listSmallMinutiae = new List<int>(); for (int j = 0; j < source.Count; j++) { int dX = source[i].X - source[j].X; int dY = source[i].Y - source[j].Y; if ((dX * dX + dY * dY) < Radius * Radius) { listSmallMinutiae.Add(j); } } listBigMinutiae.Add(new KeyValuePair<int, List<int>>(i, listSmallMinutiae)); } listBigMinutiae = listBigMinutiae.OrderByDescending(x => x.Value.Count).ToList(); List<Minutia> result = new List<Minutia>(); for (int i = 0; i < listBigMinutiae.Count; i++) { if (listBigMinutiae[i].Value.Any()) { Minutia newMinutia = new Minutia(); var circleList = listBigMinutiae[i].Value; for (int j = 0; j < listBigMinutiae[i].Value.Count; j++) { newMinutia.X += source[circleList[j]].X; newMinutia.Y += source[circleList[j]].Y; } newMinutia.X /= circleList.Count; newMinutia.Y /= circleList.Count; for (int j = i + 1; j < listBigMinutiae.Count; j++) { if(circleList.Contains(listBigMinutiae[j].Key))listBigMinutiae[j].Value.Clear(); else { listBigMinutiae[j] = new KeyValuePair<int, List<int>>(listBigMinutiae[j].Key, listBigMinutiae[j].Value.Except( circleList).ToList()); } } result.Add(newMinutia); // dX = newMinutia.X - listBigMinutiae[i][0].X; //dY = newMinutia.Y - listBigMinutiae[i][0].Y; //int min = dX*dX + dY*dY; //Minutia newMinutia1 = new Minutia(); //newMinutia1.X = listBigMinutiae[i][0].X; //newMinutia1.Y = listBigMinutiae[i][0].Y; //for (int j = 0; j < listBigMinutiae[i].Count; j++) //{ // dX = newMinutia.X - listBigMinutiae[i][j].X; // dY = newMinutia.Y - listBigMinutiae[i][j].Y; // int locmin = dX*dX + dY*dY; // if (min > locmin) // { // min = locmin; // newMinutia1.X = listBigMinutiae[i][j].X; // newMinutia1.Y = listBigMinutiae[i][j].Y; // } //} } } return result; }
private int GetCountMinutia(Minutia middleMinutia) { int sum = 0; foreach (var minutia in _minutiaeList) { if (VectorHelper.PointDistance( new PointF(minutia.X, minutia.Y), new PointF(middleMinutia.X, middleMinutia.Y)) <= Radius + 3 * SigmaLocation && !EqualsMinutae(minutia, middleMinutia)) { sum++; } } return sum; }