static void Main(string[] args) { string[] pathes = Directory.GetFiles("C:\\Users\\Tanya\\Documents\\tests_data\\db"); StreamWriter writer = new StreamWriter("C:\\Users\\Tanya\\Documents\\Results\\AlgorithmVSCOMEResult.txt", true); for (int i = 0; i < 3 /*pathes.GetLength(0)*/; i++) { Tuple <int, int> redPoint = ImageHelper.FindColorPoint(pathes[i]); double[,] imgBytes = ImageEnhancementHelper.EnhanceImage(ImageHelper.LoadImage(pathes[i])); double[,] orientationField = OrientationFieldGenerator.GenerateOrientationField(imgBytes.Select2D(x => (int)x)); Complex[,] complexOrientationField = orientationField.Select2D(x => (new Complex(Math.Cos(2 * x), Math.Sin(2 * x)))); Complex[,] filter = Filter.GetFilter(orientationField); Complex[,] complexFilteredField = ConvolutionHelper.ComplexConvolve(complexOrientationField, filter); double[,] filteredField = complexFilteredField.Select2D(x => x.Magnitude); VSCOME vscome = new VSCOME(orientationField, filteredField); double[,] vscomeValue = vscome.CalculateVscomeValue(); Tuple <int, int> corePoint = KernelHelper.Max2dPosition(vscomeValue); writer.WriteLine(GetDistance(redPoint, corePoint)); // ImageHelper.SaveArray(orientationField, "C:\\Users\\Tanya\\Documents\\Results\\orientationField.jpg"); // ImageHelper.SaveArray(filteredField, "C:\\Users\\Tanya\\Documents\\Results\\filteredField.jpg"); //ImageHelper.SaveArray(vscomeValue, "C:\\Users\\Tanya\\Documents\\Results\\vscomeValue_1.jpg"); } writer.Close(); }
public void BlurTest() { var img = ImageHelper.LoadImageAsInt(TestResources._1); var blur = OrientationFieldGenerator.GenerateBlur(img.Select2D(x => (double)x)); var path = Path.GetTempPath() + "blur.png"; ImageHelper.SaveIntArray(blur.Select2D(x => (int)x), path); Process.Start(path); }
/// <summary> /// Return double between 0 and 100. /// </summary> public static double GetBackgroundRercentage(double[,] img, int windowSize, double weight) { int badRegions = 0; //int mediumRegions = 0; int goodRegions = 0; double numberOfRegions; int[,] xGradients = OrientationFieldGenerator.GenerateXGradients(img.Select2D(a => (int)a)); int[,] yGradients = OrientationFieldGenerator.GenerateYGradients(img.Select2D(a => (int)a)); double[,] magnitudes = xGradients.Select2D( (value, x, y) => Math.Sqrt(xGradients[x, y] * xGradients[x, y] + yGradients[x, y] * yGradients[x, y])); double averege = KernelHelper.Average(magnitudes); double[,] window = new double[windowSize, windowSize]; N = (int)Math.Ceiling(((double)img.GetLength(0)) / windowSize); M = (int)Math.Ceiling(((double)img.GetLength(1)) / windowSize); numberOfRegions = N * M; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { ///////////////////////////////////////////// window = window.Select2D((value, x, y) => { if (i * windowSize + x >= magnitudes.GetLength(0) || j * windowSize + y >= magnitudes.GetLength(1)) { return(0); } return(magnitudes[(int)(i * windowSize + x), (int)(j * windowSize + y)]); }); ////////////////////////////////////////// if (KernelHelper.Average(window) < averege * weight) { badRegions++; } else { goodRegions++; } } } return(((badRegions) / numberOfRegions) * 100); }
//public static bool[,] GetMask(int[] mask1D, int maskY, int imgX, int imgY, int windowSize) //{ // bool[,] bigMask = new bool[imgX, imgY]; // bigMask = bigMask.Select2D((value, x, y) => // { // int xBlock = (int)(((double)x) / windowSize); // int yBlock = (int)(((double)y) / windowSize); // return mask1D[xBlock + yBlock * maskY] == 1; // }); // return bigMask; //} public static int[,] Segmetator(double[,] img, int windowSize, double weight, int threshold) { int[,] xGradients = OrientationFieldGenerator.GenerateXGradients(img.Select2D(a => (int)a)); int[,] yGradients = OrientationFieldGenerator.GenerateYGradients(img.Select2D(a => (int)a)); double[,] magnitudes = xGradients.Select2D( (value, x, y) => Math.Sqrt(xGradients[x, y] * xGradients[x, y] + yGradients[x, y] * yGradients[x, y])); double averege = KernelHelper.Average(magnitudes); double[,] window = new double[windowSize, windowSize]; N = (int)Math.Ceiling(((double)img.GetLength(0)) / windowSize); M = (int)Math.Ceiling(((double)img.GetLength(1)) / windowSize); int[,] mask = new int[N, M]; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { window = window.Select2D((value, x, y) => { if (i * windowSize + x >= magnitudes.GetLength(0) || j * windowSize + y >= magnitudes.GetLength(1)) { return(0); } return(magnitudes[(int)(i * windowSize + x), (int)(j * windowSize + y)]); }); if (KernelHelper.Average(window) < averege * weight) { mask[i, j] = 0; } else { mask[i, j] = 1; } } } PostProcessing(mask, threshold); return(mask); // GetBigMask(mask, img.GetLength(0), img.GetLength(1), windowSize); //return ColorImage(img, mask, windowSize); }
public float[] MakeOrientationField(float[] image, int rows, int columns, int regionSize, int overlap, bool useCuda = false) { if (useCuda) { int orFieldWidth = columns / (regionSize - overlap); int orFieldHeight = rows / (regionSize - overlap); var result = new float[orFieldWidth * orFieldHeight]; CUDAMakeOrientationField(image, columns, rows, result, regionSize, overlap); return(result); } return (OrientationFieldGenerator.GenerateOrientationField(image.Select(x => (int)x) .ToArray() .Make2D(rows, columns)) .Make1D().Select(x => (float)x).ToArray()); }
private static void PerformNewDetectionAlgorithmTestfire(int[,] imgBytes) { int radius = 5; var squaredRadius = radius * radius; var orField = OrientationFieldGenerator.GenerateOrientationField(imgBytes); //OrientationFieldGenerator.SaveField(orField,"C:\\temp\\testfire.png"); var sumField = new double[orField.GetUpperBound(0) + 1, orField.GetUpperBound(1) + 1 ]; Point maxCoords = new Point(0, 0); double max = 0; for (int x = 0; x <= orField.GetUpperBound(0); x++) { for (int y = 0; y <= orField.GetUpperBound(1); y++) { for (int i = -radius; i <= radius; i++) { if (x + i < 0 || x + i > orField.GetUpperBound(0)) { continue; } for (int j = -radius; j <= radius; j++) { if (y + j < 0 || y + j > orField.GetUpperBound(1)) { continue; } if (j * j + i * i > squaredRadius || j == 0 && i == 0) { continue; } var pointAngle = orField[x + i, y + j]; if (double.IsNaN(pointAngle)) { continue; } if (pointAngle > Math.PI * 2) { pointAngle -= Math.PI * 2; } if (pointAngle < 0) { pointAngle += Math.PI * 2; } var baseAngle = Math.Atan2(j, i); baseAngle -= Math.PI / 2; if (baseAngle < 0) { baseAngle += Math.PI * 2; } if (baseAngle > Math.PI * 2) { baseAngle -= Math.PI * 2; } double diffAngle = pointAngle - baseAngle; sumField[x, y] += Math.Abs(Math.Cos(diffAngle)); } } if (sumField[x, y] > max) { max = sumField[x, y]; maxCoords = new Point(x, y); } } } var imgCoords = new PointF( (0.5f + maxCoords.X) * (OrientationFieldGenerator.W - 1), (0.5f + maxCoords.Y) * (OrientationFieldGenerator.W - 1)); }
private static void Main() { var img = new Bitmap(Image.FromFile(".\\Fingerprints\\102_5.tif")); var imgBytes = new int[img.Size.Width, img.Size.Height]; for (var x = 0; x < img.Size.Width; x++) { for (var y = 0; y < img.Size.Height; y++) { var color = img.GetPixel(x, y); imgBytes[x, y] = (int)(.299 * color.R + .587 * color.G + .114 * color.B); } } var orfield = OrientationFieldGenerator.GenerateOrientationField(imgBytes); //VSCOMEdetector(orfield); int nFilters = 7; int nBands = 3; int bandRadius = 24; int holeRadius = 14; int nSectors = 9; var filterbank = new List <List <Tuple <int, int, double> > >(); int[,] filtersInt = new int[32, nFilters *32]; for (int i = 0; i < nFilters; i++) { filterbank.Add(CreateGaborFilter((1.0 / 10), Math.PI / nFilters * i)); } // this code was used to test the similarity of the fingerprints //var min = filterbank.SelectMany(x=>x).Select(x=>x.Item3).Min(); //var max = filterbank.SelectMany(x=>x).Select(x=>x.Item3).Max(); //for (int i = 0; i < nFilters; i++) //{ // var filter = filterbank[i]; // foreach (var tuple in filter) // { // filtersInt[tuple.Item1, tuple.Item2 + i*32] = (int) ((tuple.Item3 - min)/(max - min)*255); // } //} //Common.SaveAndShowImage(filtersInt); int size = nBands * nSectors * nFilters; int num = 60000; List <double>[] dbase = new List <double> [num]; var rand = new Random(); for (int w = 0; w < num; w++) { var lst = new List <double>(); for (int s = 0; s < size; s++) { lst.Add(rand.NextDouble() * 128.0f); } dbase[w] = lst; } using (FileStream fs = new FileStream("C:\\temp\\fusrodah_cpu_results.csv", FileMode.Create)) { using (StreamWriter streamWriter = new StreamWriter(fs)) { streamWriter.WriteLine("Find;Create;Match;Top"); for (int n = 0; n < 20; n++) { int radius = nBands * bandRadius + holeRadius + 16; //mask size var sw = new Stopwatch(); sw.Start(); PerformNewDetectionAlgorithmTestfire(imgBytes); streamWriter.Write(sw.ElapsedMilliseconds + ";"); sw.Stop(); sw.Restart(); var normalizedImage = NormalizeImage(imgBytes, nBands, holeRadius, bandRadius, 265, 292); //Common.SaveAndShowImage(normalizedImage); var filteredImages = new List <int[, ]>(); for (int i = 0; i < nFilters; i++) { filteredImages.Add(null); } Parallel.ForEach(filterbank, new ParallelOptions() { MaxDegreeOfParallelism = 4 }, filter => { var filtered = FilterWithGaborFilter(normalizedImage, filter, nBands, holeRadius, bandRadius, 265, 292); //Common.SaveAndShowImage(filtered); filteredImages[filterbank.IndexOf(filter)] = filtered; } ); var fingercode = new List <double>(); for (int i = 0; i < nFilters * nBands * nSectors; i++) { fingercode.Add(0); } Parallel.ForEach(filteredImages, new ParallelOptions { MaxDegreeOfParallelism = 4 }, filteredImgBytes => { var fingercodePart = FormFingerCode(filteredImgBytes, nSectors, nBands, holeRadius, bandRadius); int startIndex = filteredImages.IndexOf(filteredImgBytes) * nBands * nSectors; foreach (var d in fingercodePart) { fingercode[startIndex++] = d; } }); sw.Stop(); streamWriter.Write(sw.ElapsedMilliseconds + ";"); //Common.SaveFingerCode(fingercode, nBands, nSectors, nFilters, bandRadius, holeRadius); sw.Restart(); Tuple <int, double>[] result = new Tuple <int, double> [num]; Parallel.ForEach(new[] { 0, 1, 2, 3 }, new ParallelOptions() { MaxDegreeOfParallelism = 4 }, (offset) => { for (int i = 0; i < num / 4; i++) { var index = i * 4 + offset; result[index] = Tuple.Create(index, CalculateDistance(fingercode, dbase[index])); } }); sw.Stop(); streamWriter.Write(sw.ElapsedMilliseconds + ";"); sw.Restart(); result = result.OrderByDescending(x => x.Item2).ToArray(); sw.Stop(); streamWriter.WriteLine(sw.ElapsedMilliseconds); } } } }
public void LROTest() { var img = ImageHelper.LoadImageAsInt(TestResources._3); Normalizer.Normalize(100, 500, img); var path = Path.GetTempPath() + "numbers.png"; var lro = OrientationFieldGenerator.GenerateLocalRidgeOrientation(img); var image = ImageHelper.SaveArrayToBitmap(img.Select2D(x => (double)x)); const int W = OrientationFieldGenerator.W; int maxY = img.GetLength(0); int maxX = img.GetLength(1); var p = new Pen(Color.White); var g = Graphics.FromImage(image); path = Path.GetTempPath() + "lines.png"; image = ImageHelper.SaveArrayToBitmap(img.Select2D(x => (double)x)); g = Graphics.FromImage(image); // Draw grid and lines with specified tangent for (int i = 0; i < maxY / W; i++) { for (int j = 0; j < maxX / W; j++) { // point in the middle of block var middle = new Point(j * W + W / 2, i * W + W / 2); // y = (x - m.x)*tan(a) + y1 double angle = lro[i * W + W / 2, j *W + W / 2]; if (angle < 0) { angle += 2 * Math.PI; } // No difference between tan(a) and tan(a - pi), but it's more convenient to work with [0; pi] if ((angle >= Math.PI && angle <= 3 * Math.PI / 2) || angle >= 3 * Math.PI / 2 && angle <= 2 * Math.PI) { angle -= Math.PI; } // If yes, then line intersects with y-axis of current block if (angle <= Math.PI / 4 || angle >= 3 * Math.PI / 4) { // reverse of y-axis angle = Math.PI - angle; Point b = new Point(j * W, Convert.ToInt32((j * W - middle.X) * Math.Tan(angle) + middle.Y)); Point e = new Point(j * W + W, Convert.ToInt32((j * W + W - middle.X) * Math.Tan(angle) + middle.Y)); g.DrawLine(p, b, e); } else // else intersecrs with x-axis of current block { // reverse of y-axis angle = Math.PI - angle; Point b = new Point(Convert.ToInt32((i * W + W - middle.Y) / Math.Tan(angle) + middle.X), i * W + W); Point e = new Point(Convert.ToInt32((i * W - middle.Y) / Math.Tan(angle) + middle.X), i * W); g.DrawLine(p, b, e); } } } g.Save(); var res = ImageHelper.LoadImageAsInt(image); ImageHelper.SaveIntArray(res, path); Process.Start(path); }
private static void TestCUDADirections() { double[,] startImg = ImageHelper.LoadImage(Resources._7_6start); int imgHeight = startImg.GetLength(0); int imgWidth = startImg.GetLength(1); int[] mask = new int[imgHeight * imgWidth]; int windowSize = 12; float WeightConstant = 0.3F; int maskHeight = imgHeight / windowSize; int maskWidth = imgWidth / windowSize; float[] imgToSegmentator = new float[imgHeight * imgWidth]; for (int i = 0; i < imgHeight; i++) { for (int j = 0; j < imgWidth; j++) { imgToSegmentator[i * imgWidth + j] = (float)startImg[i, j]; } } CUDASegmentator(imgToSegmentator, imgWidth, imgHeight, WeightConstant, windowSize, mask, maskWidth, maskHeight); double[,] binaryImage = ImageHelper.LoadImage(Resources._7_6); //--------------------------------------- double sigma = 1.4d; double[,] smoothing = LocalBinarizationCanny.Smoothing(binaryImage, sigma); double[,] sobel = LocalBinarizationCanny.Sobel(smoothing); double[,] nonMax = LocalBinarizationCanny.NonMaximumSupperession(sobel); nonMax = GlobalBinarization.Binarization(nonMax, 60); nonMax = LocalBinarizationCanny.Inv(nonMax); int sizeWin = 16; binaryImage = LocalBinarizationCanny.LocalBinarization(binaryImage, nonMax, sizeWin, 1.3d); //--------------------------------------- binaryImage = Thining.ThinPicture(binaryImage); //--------------------------------------- List <Minutia> Minutiae = MinutiaeDetection.FindMinutiae(binaryImage); for (int i = 0; i < Minutiae.Count; i++) { if (mask[Minutiae[i].Y / windowSize * maskWidth + Minutiae[i].X / windowSize] == 0) { Minutiae.Remove(Minutiae[i]); i--; } } Minutiae = MinutiaeDetection.FindBigMinutiae(Minutiae); //-------------------------------------- int[,] intImage = ImageHelper.ConvertDoubleToInt(binaryImage); double[,] OrientationField = OrientationFieldGenerator.GenerateOrientationField(intImage); for (int i = 0; i < OrientationField.GetLength(0); i++) { for (int j = 0; j < OrientationField.GetLength(1); j++) { if (OrientationField[i, j] < 0) { OrientationField[i, j] += Math.PI; } } } //-------------------------------------- int orHeight = OrientationField.GetLength(0); int orWidth = OrientationField.GetLength(1); double[] myOrientationField = new double[orHeight * orWidth]; for (int i = 0; i < orHeight; i++) { for (int j = 0; j < orWidth; j++) { myOrientationField[i * orWidth + j] = OrientationField[i, j]; } } //--------------------------------------- int NoM = Minutiae.Count; int[] myMinutiae = new int[2 * NoM]; for (int i = 0; i < NoM; i++) { myMinutiae[2 * i] = Minutiae[i].X; myMinutiae[2 * i + 1] = Minutiae[i].Y; } //----------------------------------------------- double[] Directions = new double[NoM]; //------------------------------------------ int[] BinaryImage = new int[imgWidth * imgHeight]; for (int i = 0; i < imgHeight; i++) { for (int j = 0; j < imgWidth; j++) { BinaryImage[i * imgWidth + j] = intImage[i, j]; } } //---------------------------------------- FindDirection(myOrientationField, orHeight, orWidth, 16, myMinutiae, NoM, BinaryImage, imgHeight, imgWidth, Directions); for (int i = 0; i < NoM; i++) { var temp = Minutiae[i]; temp.Angle = Directions[i]; Minutiae[i] = temp; } var path1 = Path.GetTempPath() + "binaryImage.png"; ImageHelper.SaveArray(binaryImage, path1); var path2 = Path.GetTempPath() + "checkYourself.png"; ImageHelper.MarkMinutiaeWithDirections(path1, Minutiae, path2); Process.Start(path2); }
public static double[,] MakeOrientationField(double[,] image, int rows, int columns, int regionSize, int overlap) { return(OrientationFieldGenerator.GenerateOrientationField(image.Select2D(x => (int)x))); }