/// <summary>
        /// Draws the final shapes over the original input image.
        /// </summary>
        public static void DrawFinal(Bitmap image, List <Pair> pairs)
        {
            for (var x = 0; x < image.Width; x++)
            {
                for (var y = 0; y < image.Height; y++)
                {
                    var betweenAPair = false;
                    for (var i = 0; i < pairs.Count; i++)
                    {
                        var xl0 = -((pairs[i].L1.B - y) / pairs[i].L1.A);
                        var xl1 = -((pairs[i].l2.B - y) / pairs[i].l2.A);
                        if (x <= xl0 && x >= xl1)
                        {
                            betweenAPair = true;
                        }
                    }

                    var insideAbb = false;
                    foreach (var unused in Objects.Where(o => y > o.TopLeft.Item2 && y <o.BottomLeft.Item2 && x> o.TopLeft.Item1 && x < o.TopRight.Item1))
                    {
                        insideAbb = true;
                    }

                    if (!betweenAPair || !insideAbb)
                    {
                        continue;
                    }

                    var highlight =
                        Color.FromArgb((int)HelperFunctions.ImageClamp((int)(image.GetPixel(x, y).R + 100)), image.GetPixel(x, y).G, image.GetPixel(x, y).B);
                    image.SetPixel(x, y, highlight);
                }
            }
        }
        /// <summary>
        /// Apply convolution with a given kernel a given amount of times
        /// </summary>
        public static byte[,] Convolve(byte[,] input, float[,] kernel, int times)
        {
            var image    = new byte[input.GetLength(0), input.GetLength(1)];
            var startEnd = kernel.GetLength(0) / 2; // Adjust for all kernel sizes

            for (var x = startEnd; x < input.GetLength(0) - startEnd; x++)
            {
                for (var y = startEnd; y < input.GetLength(1) - startEnd; y++)
                {
                    float total = 0;
                    for (byte i = 0; i < kernel.GetLength(0); i++)
                    {
                        for (byte j = 0; j < kernel.GetLength(1); j++)
                        {
                            total += kernel[i, j] * input[x - startEnd + i, y - startEnd + j];
                        }
                    }
                    image[x, y] = (byte)Math.Round(HelperFunctions.ImageClamp(total));
                }
            }

            if (times > 1)
            {
                image = Convolve(image, kernel, times - 1);
            }

            HelperFunctions.GlobalMask = HelperFunctions.CropImage(HelperFunctions.GlobalMask, startEnd);
            return(HelperFunctions.CropImage(image, startEnd));
        }
        public static byte[,] Sharpen(byte[,] input, int w)
        {
            var imageToSharpen = Convolution.Convolve(input, Laplacian3X3, 1);
            var image          = new byte[imageToSharpen.GetLength(0), imageToSharpen.GetLength(1)];

            for (var x = 0; x < imageToSharpen.GetLength(0); x++)
            {
                for (var y = 0; y < imageToSharpen.GetLength(1); y++)
                {
                    image[x, y] = (byte)Math.Round(HelperFunctions.ImageClamp(input[x, y] - w * imageToSharpen[x, y]));
                }
            }


            return(image);
        }