private static void Extract( Minutiaes minutiaes, byte[] p, int i, int j, int offset, int stride, MinutiaeType type ) { //p[offset + 0] = 250; //p[offset + 1] = 120; //p[offset + 2] = 0; if (minutiaes.ContainsKey(type)) { minutiaes[type].Add((j / 3, i)); } else { minutiaes[type] = new List <(int X, int Y)>() { (j / 3, i) } }; }
public static int GetDifferences(Minutiaes first, Minutiaes second) { var values = (MinutiaeType[])Enum.GetValues(typeof(MinutiaeType)); var count = new int[values.Length]; for (int i = 0; i < first.Count; i++) { if (first.TryGetValue(values[i], out var list)) { count[i] = list.Count; } } for (int i = 0; i < first.Count; i++) { if (second.TryGetValue(values[i], out var list)) { count[i] -= list.Count; } } int sum = 0; foreach (int s in count) { sum += s > 0 ? s : -s; } return(sum); }
private void BtnApply_Click(object sender, RoutedEventArgs e) { var kmm = new Picture[this.pictures.Length]; var sw = Stopwatch.StartNew(); kmm[0] = this.pictures[0].Apply(new K3M()); this.Status.Content = $"ms: {sw.ElapsedMilliseconds} ticks: {sw.ElapsedTicks}"; for (int i = 1; i < kmm.Length; i++) { kmm[i] = this.pictures[i].Apply(new K3M()); } var cn = new Minutiaes[kmm.Length]; for (int i = 0; i < kmm.Length; i++) { cn[i] = kmm[i].CrossingNumber(); } var sb = new StringBuilder(); for (int i = 0; i < cn.Length; i++) { for (int j = 0; j < cn.Length; j++) { sb.AppendLine($"{i + 1}/{j + 1}: {Picture.GetDifferences(cn[i], cn[j])}"); } sb.AppendLine(); } this.Accuracy.Content = sb.ToString(); RefreshImages(kmm); //picture.Save("fingerprint2.png"); }
public static unsafe Bitmap GetMinutiaeExtracted(this Bitmap sourceBitmap) { BitmapData data = sourceBitmap.LockBits( new System.Drawing.Rectangle(System.Drawing.Point.Empty, sourceBitmap.Size), ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb ); byte[] p = new byte[data.Stride * data.Height]; Marshal.Copy(data.Scan0, p, 0, p.Length); sourceBitmap.UnlockBits(data); int length = data.Stride * sourceBitmap.Height; var minutiaes = new Minutiaes(); int stride = data.Stride; int height = data.Height; for (int i = 1; i < height - 1; i++) { for (int j = 3; j < stride - 3; j += 3) { int offset = i * stride + j; if (p[offset] == 255) { continue; } int sum = 0; if (IsValid(p[offset + 3])) { ++sum; } if (IsValid(p[offset - 3])) { ++sum; } for (int k = -1; k < 2; k++) { if (IsValid(p[offset + stride + k * 3])) { ++sum; } if (IsValid(p[offset - stride + k * 3])) { ++sum; } } switch (sum) { case 1: Extract(minutiaes, p, i, j, offset, stride, MinutiaeType.Ending); break; case 3: Extract(minutiaes, p, i, j, offset, stride, MinutiaeType.Bifurcation); break; case 4: Extract(minutiaes, p, i, j, offset, stride, MinutiaeType.Crossing); break; } } } Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); Marshal.Copy(p, 0, resultData.Scan0, p.Length); resultBitmap.UnlockBits(resultData); for (int k = 0; k < minutiaes[MinutiaeType.Ending].Count; k++) { for (int m = -2; m < 3; m++) { for (int n = -2; n < 3; n++) { if (minutiaes[MinutiaeType.Ending][k].X + m >= 0 && minutiaes[MinutiaeType.Ending][k].X + m < resultBitmap.Width && minutiaes[MinutiaeType.Ending][k].Y + n >= 0 && minutiaes[MinutiaeType.Ending][k].Y + n < resultBitmap.Height && (m == -2 || m == 2 || n == -2 || n == 2)) { resultBitmap.SetPixel(minutiaes[MinutiaeType.Ending][k].X + m, minutiaes[MinutiaeType.Ending][k].Y + n, Color.Red); } } } } for (int k = 0; k < minutiaes[MinutiaeType.Bifurcation].Count; k++) { for (int m = -2; m < 3; m++) { for (int n = -2; n < 3; n++) { if (minutiaes[MinutiaeType.Bifurcation][k].X + m >= 0 && minutiaes[MinutiaeType.Bifurcation][k].X + m < resultBitmap.Width && minutiaes[MinutiaeType.Bifurcation][k].Y + n >= 0 && minutiaes[MinutiaeType.Bifurcation][k].Y + n < resultBitmap.Height && (m == -2 || m == 2 || n == -2 || n == 2)) { resultBitmap.SetPixel(minutiaes[MinutiaeType.Bifurcation][k].X + m, minutiaes[MinutiaeType.Bifurcation][k].Y + n, Color.Blue); } } } } for (int k = 0; k < minutiaes[MinutiaeType.Crossing].Count; k++) { for (int m = -2; m < 3; m++) { for (int n = -2; n < 3; n++) { if (minutiaes[MinutiaeType.Crossing][k].X + m >= 0 && minutiaes[MinutiaeType.Crossing][k].X + m < resultBitmap.Width && minutiaes[MinutiaeType.Crossing][k].Y + n >= 0 && minutiaes[MinutiaeType.Crossing][k].Y + n < resultBitmap.Height && (m == -2 || m == 2 || n == -2 || n == 2)) { resultBitmap.SetPixel(minutiaes[MinutiaeType.Crossing][k].X + m, minutiaes[MinutiaeType.Crossing][k].Y + n, Color.Green); } } } } return(resultBitmap); }
public Minutiaes CrossingNumber() { var minutiaes = new Minutiaes(); BitmapData data = LockBits(ImageLockMode.ReadWrite); byte *ptr = (byte *)data.Scan0.ToPointer(); int stride = data.Stride; int height = data.Height; for (int i = 1; i < height - 1; i++) { for (int j = 3; j < stride - 3; j += 3) { int offset = i * stride + j; if (ptr[offset] == 255) { continue; } int sum = 0; if (IsValid(ptr[offset + 3])) { ++sum; } if (IsValid(ptr[offset - 3])) { ++sum; } for (int k = -1; k < 2; k++) { if (IsValid(ptr[offset + stride + k * 3])) { ++sum; } if (IsValid(ptr[offset - stride + k * 3])) { ++sum; } } switch (sum) { case 1: Extract(minutiaes, ptr, i, j, offset, MinutiaeType.Ending); break; case 3: Extract(minutiaes, ptr, i, j, offset, MinutiaeType.Bifurcation); break; case 4: Extract(minutiaes, ptr, i, j, offset, MinutiaeType.Crossing); break; } } } UnlockBits(data); return(minutiaes); }