public static PNM ApplyHoughRectanglesDetector(this PNM image, int dmax = 60, int dmin = 13) { PNM workImage = PNM.Copy(image).ApplyCannyDetector(); double maxR = Math.Sqrt(Math.Pow(image.Width / 2d, 2) + Math.Pow(image.Height / 2d, 2)); int padding = Math.Max((dmax + (dmax % 2)) / 2, (dmin + (dmin % 2)) / 2); workImage.raster = Filter.PadWithZeros(workImage.raster, image.Width * 3, image.Height, padding * 3, padding); workImage.Width += padding * 2; workImage.Height += padding * 2; int maxW = (int)Math.Ceiling(maxR); bool[] circleMask = GenerateCircleMask(dmax, dmin); int imageSize = image.Width * image.Height; IEnumerable <Tuple <float, float>[]>[] allRectangles = new IEnumerable <Tuple <float, float>[]> [image.Width]; Parallel.For(0, image.Width, i => //for (int i = 0; i < image.Width; i++) { allRectangles[i] = Enumerable.Range(0, image.Height).Select(j => { int center = workImage.Width * (padding + (int)j) + padding + i; var masked = MaskedHoughVote(workImage, center, circleMask, dmax, dmin, padding); return(masked); }).SelectMany(x => x).ToArray(); //} }); return(DrawRectangles(image, allRectangles.SelectMany(x => x).ToArray())); }
public static PNM ApplyHoughDetector(this PNM image) { // greyscale, edge detection, thresholding PNM workImage = PNM.Copy(image).ApplyPointProcessing(Color.ToGrayscale) .ApplyGradientEdgesDetection() .ApplyPointProcessing(Thresholding.Entropy(image)); IEnumerable <Tuple <Point, Point> > lines = GenerateHoughLines(workImage); return(DrawLines(image, lines)); }
public static PNM ApplyZeroCrossingDetector(this PNM image) { // preprare PNM workImage = PNM.Copy(image); Filter.Pad(workImage, 4); // apply loG Tuple <float[], float[], float[]> LoGRaster = Filter.ApplyConvolutionUnbound(workImage, LoG, 9); PNM returnImage = new PNM(image.Width, image.Height); // Apply zero crossing except last row and last column Parallel.For(0, image.Height - 1, i => { for (int j = 0; j < image.Width - 1; j++) { byte r = 0; byte g = 0; byte b = 0; // current index position int position = i * image.Width + j; float currentR = LoGRaster.Item1[position]; float neighbourR = LoGRaster.Item1[position + image.Width + 1]; float currentG = LoGRaster.Item2[position]; float neighbourG = LoGRaster.Item2[position + image.Width + 1]; float currentB = LoGRaster.Item3[position]; float neighbourB = LoGRaster.Item3[position + image.Width + 1]; if ((currentR * neighbourR) < 0 && (Math.Abs(currentR) < Math.Abs(neighbourR))) { r = 255; } if ((currentG * neighbourG) < 0 && (Math.Abs(currentG) < Math.Abs(neighbourG))) { g = 255; } if ((currentB * neighbourB) < 0 && (Math.Abs(currentB) < Math.Abs(neighbourB))) { b = 255; } returnImage.SetPixel(position, r, g, b); } }); return(returnImage); }