Пример #1
0
        /// <summary>
        /// Creates an HSV representation from an RGB image using the method describe here http://en.wikipedia.org/wiki/HSL_and_HSV#Formal_derivation
        /// </summary>
        /// <param name="input">An image in the RGB colour space</param>
        public HsvImage(RgbImage input)
        {
            //Pull dimensions from the input
            Height = input.Height;
            Width = input.Width;
            Image = new int[Width, Height][];

            //Cycle through every pixel
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    //This just follows the maths in the wiki page listed above.
                    //Again, it's fairly self-explanitory
                    int[] cell = input.Image[x, y];
                    int R = cell[0];
                    int G = cell[1];
                    int B = cell[2];

                    int M = Math.Max(Math.Max(R, G), B);
                    int m = Math.Min(Math.Min(R, G), B);
                    int C = M - m;

                    float hp;
                    if (C == 0)
                        hp = 0; //Technically undefined, but as it's a grey we can assign any value to it
                    else if (M == R)
                        hp = ((((float)G - (float)B) / (float)C) % 6 + 6) % 6;
                    else if (M == G)
                        hp = (((float)B - (float)R) / (float)C) + 2;
                    else
                        hp = (((float)R - (float)G) / (float)C) + 4;

                    int H = (int)Math.Round(60 * hp);
                    int V = M;
                    int S;
                    if (C == 0)
                        S = 0;
                    else
                        S = (255 * C) / V;

                    //Load the data in to the array
                    Image[x, y] = new int[3];
                    Image[x, y][0] = H;
                    Image[x, y][1] = S;
                    Image[x, y][2] = V;
                }
            }
        }
Пример #2
0
 /// <summary>
 /// Calculates the Root Mean Squared deviation between the RGB values of two images 
 /// </summary>
 /// <param name="comparison">The image to compare to</param>
 /// <returns>The RMSD between the RGB values of the inputs</returns>
 public int compareBitmaps(RgbImage comparison)
 {
     return (new RgbImage(this)).compareBitmaps(comparison);
 }
Пример #3
0
        /// <summary>
        /// Perform the enhancements on the waterfall image in RGB space
        /// </summary>
        static void rgbEnhance()
        {
            //Load the image
            RgbImage distorted = new RgbImage(Resources.waterfall);

            //Perform the 3 enhancements
            RgbImage brightened = distorted.brighten(1.5f);
            RgbImage logBrightened = distorted.logBrighten();
            RgbImage darkLogBrightened = logBrightened.brighten(0.5f);

            //Save out the 3 enhancements
            brightened.toBitmap().Save(@"c:\output\brightened.bmp");
            logBrightened.toBitmap().Save(@"c:\output\logBrightened.bmp");
            darkLogBrightened.toBitmap().Save(@"c:\output\darkLogBrightened.bmp");
        }
Пример #4
0
        /// <summary>
        /// Brighten the image by a log scale
        /// </summary>
        /// <returns>The brightened image</returns>
        public RgbImage logBrighten()
        {
            //create a new image to output
            RgbImage output = new RgbImage(Height, Width);
            int properties = Image[0, 0].Length;

            //Create arrays to store the largest and smallest value for each channel
            double[] Max = new double[properties];
            double[] Min = new double[properties];

            for(int i = 0; i < properties; i++){
                Max[i] = 0;
                Min[i] = 255;
            }

            //Create an array of floats to store intermediete values
            double[,][] interim = new double[Width, Height][];
            //Cycle through every pixel
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    //Cycle through every channel
                    interim[x, y] = new double[properties];
                    for (int i = 0; i < properties; i++)
                    {
                        //Take the log of the value, making sure it's above 0
                        interim[x, y][i] = Math.Max(0,Math.Log(Image[x, y][i]));

                        //Update the min/max if required
                        if (interim[x, y][i] > Max[i])
                            Max[i] = interim[x, y][i];

                        if (interim[x, y][i] < Min[i])
                            Min[i] = interim[x, y][i];
                    }
                }
            }

            //Loop through every pixel (again)
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    //Loop through every chanel
                    for (int i = 0; i < properties; i++)
                    {
                        //Normalise the value, and put it in the output image
                        output.Image[x, y][i] = (int)(255 * (Min[i] + interim[x, y][i]) / Max[i]);
                    }
                }
            }

            return output;
        }
Пример #5
0
        /// <summary>
        /// Calculates the Root Mean Squared deviation between the RGB values of two images 
        /// </summary>
        /// <param name="comparison">The image to compare to</param>
        /// <returns>The RMSD between the RGB values of the inputs</returns>
        public int compareBitmaps(RgbImage comparison)
        {
            //If the images are the same, by definition their difference is 0
            if (this == comparison)
                return 0;
            //If the widths or heights are different, no meaningful comparison can be made, therefore return the largest possible value.
            if (!(Height == comparison.Height && Width == comparison.Width))
                return (int)Int32.MaxValue;

            //Itterate over every pixel in the primary image
            int errSum = 0;
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    //Calculate the difference between each of the pixel values for this location
                    int errR = Image[x, y][0] - comparison.Image[x, y][0];
                    int errG = Image[x, y][1] - comparison.Image[x, y][1];
                    int errB = Image[x, y][2] - comparison.Image[x, y][2];
                    //Find the sum of the squares of all of the errors
                    errSum += (errR * errR) + (errB * errB) + (errG * errG);
                }
            }
            //Return the square root of the sum of squares of the errors (RMSD)
            return (int)Math.Round(Math.Sqrt(errSum));
        }
Пример #6
0
        /// <summary>
        /// Brightens the image by a linear factor
        /// </summary>
        /// <param name="factor">The factor to brighten by</param>
        /// <returns>The brightened image</returns>
        public RgbImage brighten(float factor)
        {
            //Create an empty image to output to
            RgbImage output = new RgbImage(Height, Width);
            int properties = Image[0,0].Length;
            //Cycle through all the pixels
            for (int x = 0; x < Width; x++)
            {
                for (int y = 0; y < Height; y++)
                {
                    //Cycle through all the channels of the pixel
                    for (int i = 0; i < properties; i++)
                    {
                        //Scale the value, keeping it within 0-255
                        output.Image[x, y][i] = Math.Max(0,Math.Min(255, (int)(Image[x, y][i] * factor)));
                    }
                }
            }

            return output;
        }