public virtual byte[,] Morph(byte[,] input, UseMask E) { var image = new byte[input.GetLength(0), input.GetLength(1)]; for (var x = this.StartEnd; x < input.GetLength(0) - this.StartEnd; x++) { for (var y = this.StartEnd; y < input.GetLength(1) - this.StartEnd; y++) { switch (E) { case UseMask.Binary when HelperFunctions.GlobalMask[x, y] == 255: { var localArea = new List <float>(this.Kernel.GetLength(0) * this.Kernel.GetLength(0)); // storage of local area for (byte i = 0; i < this.Kernel.GetLength(0); i++) { for (byte j = 0; j < this.Kernel.GetLength(1); j++) { if (HelperFunctions.GlobalMask[x - this.StartEnd + i, y - this.StartEnd + j] == 255) { image[x, y] = Filter(x, y, i, j, localArea, input, 100, E); } } } break; } // don't filter this pixel case UseMask.Binary: image[x, y] = input[x, y]; break; case UseMask.Greyscale: { var localArea = new List <float>(this.Kernel.GetLength(0) * this.Kernel.GetLength(0)); // storage of local area for (byte i = 0; i < this.Kernel.GetLength(0); i++) { for (byte j = 0; j < this.Kernel.GetLength(1); j++) { image[x, y] = Filter(x, y, i, j, localArea, input, HelperFunctions.GlobalMask[x, y], E); // use the mask's position as the max or min clamp value for grayscale masks } } break; } default: { var localArea = new List <float>(this.Kernel.GetLength(0) * this.Kernel.GetLength(0)); // storage of local area for (byte i = 0; i < this.Kernel.GetLength(0); i++) { for (byte j = 0; j < this.Kernel.GetLength(1); j++) { image[x, y] = Filter(x, y, i, j, localArea, input, 100, E); // Perform the normal erosion/dilation without a mask (the 100 argument here gets changed in Filter) } } break; } } } } if (this.Times > 1) { this.Times--; image = Morph(image, E); } Console.WriteLine("[Morphology] Dilation or Erosion was applied " + this.Times + " time(s) with a " + this.Kernel.GetLength(0) + "x" + this.Kernel.GetLength(1) + " kernel with " + E + " Mask."); HelperFunctions.GlobalMask = HelperFunctions.CropImage(HelperFunctions.GlobalMask, this.StartEnd); return(HelperFunctions.CropImage(image, this.StartEnd)); }
private void applyButton_Click(object sender, EventArgs e) { if (this._inputImage == null) { return; } this._outputImage?.Dispose(); this._outputImage = new Bitmap(this._inputImage.Size.Width, this._inputImage.Size.Height); var image = new Color[this._inputImage.Size.Width, this._inputImage.Size.Height]; var image2 = new Color[this._inputImage2.Size.Width, this._inputImage2.Size.Height]; // Setup progress bar this.progressBar.Visible = true; this.progressBar.Minimum = 1; this.progressBar.Maximum = this._inputImage.Size.Width * this._inputImage.Size.Height; this.progressBar.Value = 1; this.progressBar.Step = 1; // Copy input Bitmap to array for (var x = 0; x < this._inputImage.Size.Width; x++) { for (var y = 0; y < this._inputImage.Size.Height; y++) { image[x, y] = this._inputImage.GetPixel(x, y); // Set pixel color in array at (x,y) } } // Copy input Bitmap to array for the control image for (var x = 0; x < this._inputImage2.Size.Width; x++) { for (var y = 0; y < this._inputImage2.Size.Height; y++) { image2[x, y] = this._inputImage2.GetPixel(x, y); // Set pixel color in array at (x,y) } } //================================================================================== //================================= PIPELINE ======================================= //================================================================================== //RESET VARS FROM PREVIOUS IMAGE: FloodFill.ObjectCount = 0; FloodFill.Objects = new List <PictureObject>(); //===================== Preprocessing: Filtering, Segmentation ===================== var greyscale = HelperFunctions.Greyscalize(image); HelperFunctions.GlobalMask = HelperFunctions.Greyscalize(image2); //===================== Edge Detection ============================================= var detectSides = CannyEdge.CannyEdgeDetector(greyscale, 1, GlobalThreshold.OtsuThreshold(greyscale)); //===================== Find sides of road poles using Hough transform ============= var lines = HoughTransform.FoundLines(detectSides, 0, 0); var cartLines = HoughExtensions.GetAllCartesianLines(lines, detectSides); var pairs = HoughExtensions.GetPairs(cartLines, detectSides.GetLength(1)); var roughPairs = HoughExtensions.GetRoughPairs(cartLines, detectSides.GetLength(1)); //===================== Find lower and upper boundaries of poles =================== var workingImage = BilateralFilter.BilateralFilter2D(greyscale); workingImage = EdgeDetection.DetectEdges(HelperFunctions.Threshold(workingImage, GlobalThreshold.OtsuThreshold(workingImage))); detectSides = HoughExtensions.CleanOutsidePairs(workingImage, roughPairs); detectSides = FloodFill.MarkObjects(detectSides); detectSides = FloodFill.filterObjects(detectSides); //================================================================================== //================================================================================== //================================================================================== var nDV = ValueCounter(detectSides); this.label2.Text = "Number of distinct values: " + nDV; Console.ForegroundColor = ConsoleColor.Magenta; Console.WriteLine("[Done] Final image with size " + detectSides.GetLength(0) + "x" + detectSides.GetLength(1) + " and " + nDV + " distinct Values"); Console.ResetColor(); var newImage = Colorize(detectSides); DrawBoundingBox(newImage); var outputResized = new Bitmap(this._outputImage, detectSides.GetLength(0), detectSides.GetLength(1)); // Copy array to output Bitmap for (var x = 0; x < newImage.GetLength(0); x++) { for (var y = 0; y < newImage.GetLength(1); y++) { outputResized.SetPixel(x, y, newImage[x, y]); // Set the pixel color at coordinate (x,y) } } var g = Graphics.FromImage(outputResized); DrawPairs(pairs, outputResized); // Draw pairs generated by hough transform FloodFill.DrawFinal(this._inputImage, pairs); pictureBox2.Image = this._inputImage; // Display output image - replace InputImage with OutputResized to see hough pairs and object map with bounding boxes progressBar.Visible = true; // Hide progress bar }