Exemple #1
0
        private PixImage GetSubImage(int x, int y, int width, int height)
        {
            PixImage newImage = new PixImage(width, height);

            for (int i = x; i < x + width; i++)
            {
                for (int j = y; j < y + height; j++)
                {
                    newImage.setPixel(i - x, j - y, this.getRed(i, j), this.getGreen(i, j), this.getBlue(i, j));
                }
            }
            return(newImage);
        }
Exemple #2
0
        /// <summary>
        /// array2PixImage() converts a 2D array of grayscale intensities to
        /// a grayscale PixImage.
        /// </summary>
        /// <param name="pixels"> a 2D array of grayscale intensities in the range 0...255. </param>
        /// <returns> a new PixImage whose red, green, and blue values are equal to
        /// the input grayscale intensities. </returns>
        private static PixImage array2PixImage(int[][] pixels)
        {
            int      width  = pixels.Length;
            int      height = pixels[0].Length;
            PixImage image  = new PixImage(width, height);

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    image.setPixel(x, y, (short)pixels[x][y], (short)pixels[x][y], (short)pixels[x][y]);
                }
            }

            return(image);
        }
Exemple #3
0
        //this helper function returns a new PixImage with pixels on the edges reflected across the axis
        //so that each pixel in the original image has 9 neighbors (including itself)
        private PixImage GetReflection()
        {
            var newMatrix = new PixImage(Width + 2, Height + 2);

            for (int x = 1; x < newMatrix.Width - 1; x++)
            {
                for (int y = 1; y < newMatrix.Height - 1; y++)
                {
                    newMatrix.setPixel(x, y, this.getRed(x - 1, y - 1), this.getGreen(x - 1, y - 1), this.getBlue(x - 1, y - 1));
                }
            }

            for (int x = 0; x < newMatrix.Width; x++)
            {
                for (int y = 0; y < newMatrix.Height; y++)
                {
                    int   a   = x;
                    int   b   = y;
                    short red = 0;

                    if (x == 0)
                    {
                        a = 1;
                    }
                    if (y == 0)
                    {
                        b = 1;
                    }
                    if (x == newMatrix.Width - 1)
                    {
                        a = newMatrix.Width - 2;
                    }
                    if (y == newMatrix.Height - 1)
                    {
                        b = newMatrix.Height - 2;
                    }
                    red = (short)newMatrix.getRed(a, b);

                    //Console.WriteLine("getting a: {0}, b: {1}, for x: {2}, y: {3} which is: {4}", a,  b, x, y, red);
                    newMatrix.setPixel(x, y, red, red, red);
                }
            }
            //Console.WriteLine(newMatrix);
            return(newMatrix);
        }
Exemple #4
0
        /// <summary>
        /// sobelEdges() applies the Sobel operator, identifying edges in "this"
        /// image.  The Sobel operator computes a magnitude that represents how
        /// strong the edge is.  We compute separate gradients for the red, blue, and
        /// green components at each pixel, then sum the squares of the three
        /// gradients at each pixel.  We convert the squared magnitude at each pixel
        /// into a grayscale pixel intensity in the range 0...255 with the logarithmic
        /// mapping encoded in mag2gray().  The output is a grayscale PixImage whose
        /// pixel intensities reflect the strength of the edges.
        ///
        /// See http://en.wikipedia.org/wiki/Sobel_operator#Formulation for details.
        /// </summary>
        /// <returns> a grayscale PixImage representing the edges of the input image.
        /// Whiter pixels represent stronger edges. </returns>
        public virtual PixImage SobelEdges()
        {
            var newImage = new PixImage(this.Width, this.Height);

            //constant, Sobel operator
            int[,] xSobelOperator =
            {
                { 1, 0, -1 },
                { 2, 0, -2 },
                { 1, 0, -1 }
            };

            //constant, Sobel operator
            int[,] ySobelOperator =
            {
                {  1,  2,  1 },
                {  0,  0,  0 },
                { -1, -2, -1 }
            };

            int[] gx, gy;
            long[,] energy = new long[Width, Height];

            //get reflection so every pixel within the original image has 9 neighbors (incl itself)
            var newImageWithReflection = this.GetReflection();

            //traverse each pixel within original image and calculate dot product
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    //get subimage for each pixel (from newImageWithReflection)
                    var image = newImageWithReflection.GetSubImage(i, j, 3, 3);

                    //calculate dot product with x and y sobel operators
                    gx = image.DotProduct(xSobelOperator);
                    gy = image.DotProduct(ySobelOperator);

                    //calculate energy values
                    energy[i, j] = (gx[0] * gx[0]) + (gy[0] * gy[0]) + (gx[1] * gx[1]) + (gy[1] * gy[1]) + (gx[2] * gx[2]) + (gy[2] * gy[2]);
                    newImage.setPixel(i, j, mag2gray(energy[i, j]), mag2gray(energy[i, j]), mag2gray(energy[i, j]));
                }
            }
            return(newImage);
        }
Exemple #5
0
        /// <summary>
        /// equals() checks whether two images are the same, i.e. have the same
        /// dimensions and pixels.
        /// </summary>
        /// <param name="image"> a PixImage to compare with "this" PixImage. </param>
        /// <returns> true if the specified PixImage is identical to "this" PixImage. </returns>
        public virtual bool Equals(PixImage image)
        {
            int width  = Width;
            int height = Height;

            if (image == null || width != image.Width || height != image.Height)
            {
                return(false);
            }

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (!(getRed(x, y) == image.getRed(x, y) && getGreen(x, y) == image.getGreen(x, y) && getBlue(x, y) == image.getBlue(x, y)))
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Exemple #6
0
 /// <summary>
 /// boxBlur() returns a blurred version of "this" PixImage.
 ///
 /// If numIterations == 1, each pixel in the output PixImage is assigned
 /// a value equal to the average of its neighboring pixels in "this" PixImage,
 /// INCLUDING the pixel itself.
 ///
 /// A pixel not on the image boundary has nine neighbors--the pixel itself and
 /// the eight pixels surrounding it.  A pixel on the boundary has six
 /// neighbors if it is not a corner pixel; only four neighbors if it is
 /// a corner pixel.  The average of the neighbors is the sum of all the
 /// neighbor pixel values (including the pixel itself) divided by the number
 /// of neighbors, with non-integer quotients rounded toward zero (as C# does
 /// naturally when you divide two integers).
 ///
 /// Each color (red, green, blue) is blurred separately.  The red input should
 /// have NO effect on the green or blue outputs, etc.
 ///
 /// The parameter numIterations specifies a number of repeated iterations of
 /// box blurring to perform.  If numIterations is zero or negative, "this"
 /// PixImage is returned (not a copy).  If numIterations is positive, the
 /// return value is a newly constructed PixImage.
 ///
 /// IMPORTANT:  DO NOT CHANGE "this" PixImage!!!  All blurring/changes should
 /// appear in the new, output PixImage only.
 /// </summary>
 /// <param name="numIterations"> the number of iterations of box blurring. </param>
 /// <returns> a blurred version of "this" PixImage. </returns>
 public virtual PixImage BoxBlur(int numIterations)
 {
     if (numIterations > 0)
     {
         //make a new image
         var newImage = new PixImage(this.Width, this.Height);
         for (int i = 0; i < this.Width; i++)
         {
             for (int j = 0; j < this.Height; j++)
             {
                 Pixel newPixel = this.GetBlurredPixel(i, j);
                 newImage.setPixel(i, j, newPixel.Red, newPixel.Green, newPixel.Blue);
                 // Console.WriteLine("At pixel {0},{1}: {2}, {3}, {4}. Counter: {5}", i, j, red, green, blue, counter);
             }
         }
         for (int n = 0; n < numIterations; n++)
         {
             newImage = newImage.BoxBlur(n);
         }
         return(newImage);
     }
     return(this);
 }
Exemple #7
0
        /// <summary>
        /// main() runs a series of tests to ensure that the convolutions (box blur
        /// and Sobel) are correct.
        /// </summary>
        public static void Main(string[] args)
        {
            // Be forwarned that when you write arrays directly in C# as below,
            // each "row" of text is a column of your image--the numbers get
            // transposed.
            PixImage image1 = array2PixImage(new int[][]
            {
                new int[] { 0, 10, 240 },
                new int[] { 30, 120, 250 },
                new int[] { 80, 250, 255 }
            });

            Console.WriteLine("Testing getWidth/getHeight on a 3x3 image.  " + "Input image:");
            Console.Write(image1);
            doTest(image1.Width == 3 && image1.Height == 3, "Incorrect image width and height.");

            Console.WriteLine("Testing blurring on a 3x3 image.");
            doTest(image1.BoxBlur(1).Equals(array2PixImage(new int[][]
            {
                new int[] { 40, 108, 155 },
                new int[] { 81, 137, 187 },
                new int[] { 120, 164, 218 }
            })), "Incorrect box blur (1 rep):\n" + image1.BoxBlur(1));
            doTest(image1.BoxBlur(2).Equals(array2PixImage(new int[][]
            {
                new int[] { 91, 118, 146 },
                new int[] { 108, 134, 161 },
                new int[] { 125, 151, 176 }
            })), "Incorrect box blur (2 rep):\n" + image1.BoxBlur(2));
            doTest(image1.BoxBlur(2).Equals(image1.BoxBlur(1).BoxBlur(1)), "Incorrect box blur (1 rep + 1 rep):\n" + image1.BoxBlur(2) + image1.BoxBlur(1).BoxBlur(1));

            Console.WriteLine("Testing edge detection on a 3x3 image.");
            doTest(image1.SobelEdges().Equals(array2PixImage(new int[][]
            {
                new int[] { 104, 189, 180 },
                new int[] { 160, 193, 157 },
                new int[] { 166, 178, 96 }
            })), "Incorrect Sobel:\n" + image1.SobelEdges());

            PixImage image2 = array2PixImage(new int[][]
            {
                new int[] { 0, 100, 100 },
                new int[] { 0, 0, 100 }
            });

            Console.WriteLine("Testing getWidth/getHeight on a 2x3 image.  " + "Input image:");
            Console.Write(image2);
            doTest(image2.Width == 2 && image2.Height == 3, "Incorrect image width and height.");

            Console.WriteLine("Testing blurring on a 2x3 image.");
            doTest(image2.BoxBlur(1).Equals(array2PixImage(new int[][]
            {
                new int[] { 25, 50, 75 },
                new int[] { 25, 50, 75 }
            })), "Incorrect box blur (1 rep):\n" + image2.BoxBlur(1));

            Console.WriteLine("Testing edge detection on a 2x3 image.");
            doTest(image2.SobelEdges().Equals(array2PixImage(new int[][]
            {
                new int[] { 122, 143, 74 },
                new int[] { 74, 143, 122 }
            })), "Incorrect Sobel:\n" + image2.SobelEdges());
            Console.ReadLine();
        }