示例#1
0
        /// <summary>
        /// Calculate Gradient vector between the given pixel and its right and bottom ones
        /// </summary>
        /// <param name="x">pixel x-coordinate</param>
        /// <param name="y">pixel y-coordinate</param>
        /// <param name="ImageMatrix">colored image matrix</param>
        /// <returns></returns>
        private static Vector2D CalculateGradientAtPixel(int x, int y, RGBPixel[,] ImageMatrix)
        {
            Vector2D gradient     = new Vector2D(0, 0);
            RGBPixel mainPixel    = ImageMatrix[y, x];
            double   pixelGrayVal = 0.21 * mainPixel.red + 0.72 * mainPixel.green + 0.07 * mainPixel.blue;

            if (y == GetHeight(ImageMatrix) - 1)
            {
                //boundary pixel.
                //for (int i = 0; i < 3; i++)
                //{
                gradient.Y = 0;
                //}
            }
            else
            {
                RGBPixel downPixel        = ImageMatrix[y + 1, x];
                double   downPixelGrayVal = 0.21 * downPixel.red + 0.72 * downPixel.green + 0.07 * downPixel.blue;
                gradient.Y = pixelGrayVal - downPixelGrayVal;
            }
            if (x == GetWidth(ImageMatrix) - 1)
            {
                //boundary pixel.
                gradient.X = 0;
            }
            else
            {
                RGBPixel rightPixel        = ImageMatrix[y, x + 1];
                double   rightPixelGrayVal = 0.21 * rightPixel.red + 0.72 * rightPixel.green + 0.07 * rightPixel.blue;
                gradient.X = pixelGrayVal - rightPixelGrayVal;
            }
            return(gradient);
        }
 public static RGBPixel[,] fill(List<Point> selected_points, RGBPixel[,] ImageMatrix)
 {
     Boundary bondry = GET_Boundary(selected_points); // Boundary of the main selection
     selected_image = Helper.COPY_Segment(ImageMatrix,bondry); // get croped image 
     block_border(selected_points,bondry);                     // assign the selected point as blocks
     Flood_Fill(ImageOperations.GetWidth(selected_image) - 1, ImageOperations.GetHeight(selected_image) - 1);
     return selected_image;
 }
示例#3
0
        public static RGBPixel[,] CopyImage(RGBPixel[,] ImageMatrix, Boundary border)
        {
            int Width  = border.MAX_X - border.MIN_X;
            int Height = border.MAX_Y - border.MIN_Y;

            RGBPixel[,] SelectedImage = new RGBPixel[Height + 1, Width + 1];
            for (int i = 0; i <= Height; i++)
            {
                for (int j = 0; j <= Width; j++)
                {
                    SelectedImage[i, j] = ImageMatrix[border.MIN_Y + i, border.MIN_X + j];
                }
            }
            return(SelectedImage);
        }
示例#4
0
        public static RGBPixel[ , ] COPY(RGBPixel [ , ] ImageMatrix)
        {
            int Width  = ImageOperations.GetWidth(ImageMatrix);
            int Height = ImageOperations.GetHeight(ImageMatrix);


            RGBPixel[,] selected_image = new RGBPixel[Height, Width];
            for (int r = 0; r < Height; r++)
            {
                for (int c = 0; c < Width; c++)
                {
                    selected_image [r, c] = ImageMatrix [r, c];
                }
            }

            return(selected_image);
        }
示例#5
0
        public static RGBPixel[ , ] COPY_Segment(RGBPixel [ , ] ImageMatrix, Boundary bondry)
        {
            // copy a segment  from image matrix into anew one
            int Width  = bondry.MAX_X - bondry.MIN_X; // new segment widtrh
            int Height = bondry.MAX_Y - bondry.MIN_Y; // new segment height


            RGBPixel[,] selected_image = new RGBPixel[Height + 1, Width + 1];
            for (int r = 0; r <= Height; r++)
            {
                for (int c = 0; c <= Width; c++)
                {
                    selected_image [r, c] = ImageMatrix [bondry.MIN_Y + r, bondry.MIN_X + c];
                }
            }

            return(selected_image);
        }
 public CropedImage(RGBPixel[,] cropedImage)
 {
     InitializeComponent();
     ImageOperations.DisplayImage(cropedImage, pictureBox1);
 }
 /// <summary>
 /// generate the shortest path from source node to all other nodes
 /// </summary>
 /// <param name="Graph"></param>
 /// <param name="Source"></param>
 /// <param name="Dest"></param>
 /// <returns></returns>
 public static List<Point> GenerateShortestPath(int Source, int Dest, RGBPixel[,] ImageMatrix)
 {
     // return sortest path btween src & all other nodes 
     List<int> Previous_list = Dijkstra(Source, Dest, ImageMatrix);
     // Backtracking shortest path to (Dest)node  from previous list 
     return Backtracking(Previous_list, Dest, ImageOperations.GetWidth(ImageMatrix));
 }
 /// <summary>
 /// Get the width of the image 
 /// </summary>
 /// <param name="ImageMatrix">2D array that contains the image</param>
 /// <returns>Image Width</returns>
 public static int GetWidth(RGBPixel[,] ImageMatrix)
 {
     return ImageMatrix.GetLength(1);
 }
 /// <summary>
 /// Calculate Gradient vector between the given pixel and its right and bottom ones
 /// </summary>
 /// <param name="x">pixel x-coordinate</param>
 /// <param name="y">pixel y-coordinate</param>
 /// <param name="ImageMatrix">colored image matrix</param>
 /// <returns></returns>
 private static Vector2D CalculateGradientAtPixel(int x, int y, RGBPixel[,] ImageMatrix)
 {
     Vector2D gradient = new Vector2D(0, 0);
     RGBPixel mainPixel = ImageMatrix[y, x];
     double pixelGrayVal = 0.21 * mainPixel.red + 0.72 * mainPixel.green + 0.07 * mainPixel.blue;
     if (y == GetHeight(ImageMatrix) - 1)
     {
         //boundary pixel.
         for (int i = 0; i < 3; i++)
         {
             gradient.Y = 0;
         }
     }
     else
     {
         RGBPixel downPixel = ImageMatrix[y + 1, x];
         double downPixelGrayVal = 0.21 * downPixel.red + 0.72 * downPixel.green + 0.07 * downPixel.blue;
         gradient.Y = pixelGrayVal - downPixelGrayVal;
     }
     if (x == GetWidth(ImageMatrix) - 1)
     {
         //boundary pixel.
         gradient.X = 0;
     }
     else
     {
         RGBPixel rightPixel = ImageMatrix[y, x + 1];
         double rightPixelGrayVal = 0.21 * rightPixel.red + 0.72 * rightPixel.green + 0.07 * rightPixel.blue;
         gradient.X = pixelGrayVal - rightPixelGrayVal;
     }
     return gradient;
 }
        /// <summary>
        /// Open an image and load it into 2D array of colors (size: Height x Width)
        /// </summary>
        /// <param name="ImagePath">Image file path</param>
        /// <returns>2D array of colors</returns>
        public static RGBPixel[,] OpenImage(string ImagePath)
        {
            Bitmap original_bm = new Bitmap(ImagePath);
            int Height = original_bm.Height;
            int Width = original_bm.Width;

            RGBPixel[,] Buffer = new RGBPixel[Height, Width]; // Load the image to the 2D-array

            unsafe
            {
                BitmapData bmd = original_bm.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, original_bm.PixelFormat);
                int x, y;
                int nWidth = 0;
                bool Format32 = false;
                bool Format24 = false;
                bool Format8 = false;

                if (original_bm.PixelFormat == PixelFormat.Format24bppRgb)
                {
                    Format24 = true;
                    nWidth = Width * 3;
                }
                else if (original_bm.PixelFormat == PixelFormat.Format32bppArgb || original_bm.PixelFormat == PixelFormat.Format32bppRgb || original_bm.PixelFormat == PixelFormat.Format32bppPArgb)
                {
                    Format32 = true;
                    nWidth = Width * 4;
                }
                else if (original_bm.PixelFormat == PixelFormat.Format8bppIndexed)
                {
                    Format8 = true;
                    nWidth = Width;
                }
                int nOffset = bmd.Stride - nWidth;
                byte* p = (byte*)bmd.Scan0;
                for (y = 0; y < Height; y++)
                {
                    for (x = 0; x < Width; x++)
                    {
                        if (Format8)
                        {
                            Buffer[y, x].red = Buffer[y, x].green = Buffer[y, x].blue = p[0];
                            p++;
                        }
                        else
                        {
                            Buffer[y, x].red = p[0];
                            Buffer[y, x].green = p[1];
                            Buffer[y, x].blue = p[2];
                            if (Format24) p += 3;
                            else if (Format32) p += 4;
                        }
                    }
                    p += nOffset;
                }
                original_bm.UnlockBits(bmd);
            }
            //////////////////////////////////////////////
            //Additional part to initialize pixels as not visited yet.
            //////////////////////////////////////////////
            for (int y = 0; y < Height; y++)
                for (int x = 0; x < Width; x++)
                    Buffer[y, x].block = false;
            return Buffer;
        }
        /// <summary>
        /// Apply Gaussian smoothing filter to enhance the edge detection 
        /// </summary>
        /// <param name="ImageMatrix">Colored image matrix</param>
        /// <param name="filterSize">Gaussian mask size</param>
        /// <param name="sigma">Gaussian sigma</param>
        /// <returns>smoothed color image</returns>
        public static RGBPixel[,] GaussianFilter1D(RGBPixel[,] ImageMatrix, int filterSize, double sigma)
        {
            int Height = GetHeight(ImageMatrix);
            int Width = GetWidth(ImageMatrix);
            RGBPixelD[,] VerFiltered = new RGBPixelD[Height, Width];
            RGBPixel[,] Filtered = new RGBPixel[Height, Width];
            // Create Filter in Spatial Domain:
            //=================================
            //make the filter ODD size
            if (filterSize % 2 == 0) filterSize++;

            double[] Filter = new double[filterSize];

            //Compute Filter in Spatial Domain :
            //==================================
            double Sum1 = 0;
            int HalfSize = filterSize / 2;
            for (int y = -HalfSize; y <= HalfSize; y++)
            {
                //Filter[y+HalfSize] = (1.0 / (Math.Sqrt(2 * 22.0/7.0) * Segma)) * Math.Exp(-(double)(y*y) / (double)(2 * Segma * Segma)) ;
                Filter[y + HalfSize] = Math.Exp(-(double)(y * y) / (double)(2 * sigma * sigma));
                Sum1 += Filter[y + HalfSize];
            }
            for (int y = -HalfSize; y <= HalfSize; y++)
            {
                Filter[y + HalfSize] /= Sum1;
            }

            //Filter Original Image Vertically:
            //=================================
            int ii, jj;
            RGBPixelD Sum;
            RGBPixel Item1;
            RGBPixelD Item2;

            for (int j = 0; j < Width; j++)
                for (int i = 0; i < Height; i++)
                {
                    Sum.red = 0;
                    Sum.green = 0;
                    Sum.blue = 0;
                    for (int y = -HalfSize; y <= HalfSize; y++)
                    {
                        ii = i + y;
                        if (ii >= 0 && ii < Height)
                        {
                            Item1 = ImageMatrix[ii, j];
                            Sum.red += Filter[y + HalfSize] * Item1.red;
                            Sum.green += Filter[y + HalfSize] * Item1.green;
                            Sum.blue += Filter[y + HalfSize] * Item1.blue;
                        }
                    }
                    VerFiltered[i, j] = Sum;
                }

            //Filter Resulting Image Horizontally:
            //===================================
            for (int i = 0; i < Height; i++)
                for (int j = 0; j < Width; j++)
                {
                    Sum.red = 0;
                    Sum.green = 0;
                    Sum.blue = 0;
                    for (int x = -HalfSize; x <= HalfSize; x++)
                    {
                        jj = j + x;
                        if (jj >= 0 && jj < Width)
                        {
                            Item2 = VerFiltered[i, jj];
                            Sum.red += Filter[x + HalfSize] * Item2.red;
                            Sum.green += Filter[x + HalfSize] * Item2.green;
                            Sum.blue += Filter[x + HalfSize] * Item2.blue;
                        }
                    }
                    Filtered[i, j].red = (byte)Sum.red;
                    Filtered[i, j].green = (byte)Sum.green;
                    Filtered[i, j].blue = (byte)Sum.blue;
                }
            for (int y = 0; y < Height; y++)
                for (int x = 0; x < Width; x++)
                    Filtered[y, x].block = false;
            return Filtered;
        }
        /// <summary>
        /// Display the given image on the given PictureBox object
        /// </summary>
        /// <param name="ImageMatrix">2D array that contains the image</param>
        /// <param name="PicBox">PictureBox object to display the image on it</param>
        public static void DisplayImage(RGBPixel[,] ImageMatrix, PictureBox PicBox)
        {
            // Create Image:
            //==============
            int Height = ImageMatrix.GetLength(0);
            int Width = ImageMatrix.GetLength(1);

            Bitmap ImageBMP = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);

            unsafe
            {
                BitmapData bmd = ImageBMP.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, ImageBMP.PixelFormat);
                int nWidth = 0;
                nWidth = Width * 3;
                int nOffset = bmd.Stride - nWidth;
                byte* p = (byte*)bmd.Scan0;
                for (int i = 0; i < Height; i++)
                {
                    for (int j = 0; j < Width; j++)
                    {
                        p[0] = ImageMatrix[i, j].red;
                        p[1] = ImageMatrix[i, j].green;
                        p[2] = ImageMatrix[i, j].blue;
                        p += 3;
                    }

                    p += nOffset;
                }
                ImageBMP.UnlockBits(bmd);
            }
            PicBox.Image = ImageBMP;
        }
 /// <summary>
 /// Calculate edge energy between
 ///     1. the given pixel and its right one (X)
 ///     2. the given pixel and its bottom one (Y)
 /// </summary>
 /// <param name="x">pixel x-coordinate</param>
 /// <param name="y">pixel y-coordinate</param>
 /// <param name="ImageMatrix">colored image matrix</param>
 /// <returns>edge energy with the right pixel (X) and with the bottom pixel (Y)</returns>
 public static Vector2D CalculatePixelEnergies(int x, int y, RGBPixel[,] ImageMatrix)
 {
     if (ImageMatrix == null)
         throw new Exception("image is not set!");
     Vector2D gradient = CalculateGradientAtPixel(x, y, ImageMatrix);
     double gradientMagnitude = Math.Sqrt(gradient.X * gradient.X + gradient.Y * gradient.Y);
     double edgeAngle = Math.Atan2(gradient.Y, gradient.X);
     double rotatedEdgeAngle = edgeAngle + Math.PI / 2.0;
     Vector2D energy = new Vector2D(
      Math.Abs(gradientMagnitude * Math.Cos(rotatedEdgeAngle)),
      Math.Abs(gradientMagnitude * Math.Sin(rotatedEdgeAngle)));
     return energy;
 }
示例#14
0
        /// <summary>
        /// Apply Gaussian smoothing filter to enhance the edge detection
        /// </summary>
        /// <param name="ImageMatrix">Colored image matrix</param>
        /// <param name="filterSize">Gaussian mask size</param>
        /// <param name="sigma">Gaussian sigma</param>
        /// <returns>smoothed color image</returns>
        public static RGBPixel[,] GaussianFilter1D(RGBPixel[,] ImageMatrix, int filterSize, double sigma)
        {
            int Height = GetHeight(ImageMatrix);
            int Width  = GetWidth(ImageMatrix);

            RGBPixelD[,] VerFiltered = new RGBPixelD[Height, Width];
            RGBPixel[,] Filtered     = new RGBPixel[Height, Width];


            // Create Filter in Spatial Domain:
            //=================================
            //make the filter ODD size
            if (filterSize % 2 == 0)
            {
                filterSize++;
            }

            double[] Filter = new double[filterSize];

            //Compute Filter in Spatial Domain :
            //==================================
            double Sum1     = 0;
            int    HalfSize = filterSize / 2;

            for (int y = -HalfSize; y <= HalfSize; y++)
            {
                //Filter[y+HalfSize] = (1.0 / (Math.Sqrt(2 * 22.0/7.0) * Segma)) * Math.Exp(-(double)(y*y) / (double)(2 * Segma * Segma)) ;
                Filter[y + HalfSize] = Math.Exp(-(double)(y * y) / (double)(2 * sigma * sigma));
                Sum1 += Filter[y + HalfSize];
            }
            for (int y = -HalfSize; y <= HalfSize; y++)
            {
                Filter[y + HalfSize] /= Sum1;
            }

            //Filter Original Image Vertically:
            //=================================
            int       ii, jj;
            RGBPixelD Sum;
            RGBPixel  Item1;
            RGBPixelD Item2;

            for (int j = 0; j < Width; j++)
            {
                for (int i = 0; i < Height; i++)
                {
                    Sum.red   = 0;
                    Sum.green = 0;
                    Sum.blue  = 0;
                    for (int y = -HalfSize; y <= HalfSize; y++)
                    {
                        ii = i + y;
                        if (ii >= 0 && ii < Height)
                        {
                            Item1      = ImageMatrix[ii, j];
                            Sum.red   += Filter[y + HalfSize] * Item1.red;
                            Sum.green += Filter[y + HalfSize] * Item1.green;
                            Sum.blue  += Filter[y + HalfSize] * Item1.blue;
                        }
                    }
                    VerFiltered[i, j] = Sum;
                }
            }

            //Filter Resulting Image Horizontally:
            //===================================
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    Sum.red   = 0;
                    Sum.green = 0;
                    Sum.blue  = 0;
                    for (int x = -HalfSize; x <= HalfSize; x++)
                    {
                        jj = j + x;
                        if (jj >= 0 && jj < Width)
                        {
                            Item2      = VerFiltered[i, jj];
                            Sum.red   += Filter[x + HalfSize] * Item2.red;
                            Sum.green += Filter[x + HalfSize] * Item2.green;
                            Sum.blue  += Filter[x + HalfSize] * Item2.blue;
                        }
                    }
                    Filtered[i, j].red   = (byte)Sum.red;
                    Filtered[i, j].green = (byte)Sum.green;
                    Filtered[i, j].blue  = (byte)Sum.blue;
                }
            }

            return(Filtered);
        }
        public static List<int> Dijkstra(int Source, int dest, RGBPixel[,] ImageMatrix)
        {
            const double oo = 10000000000000000000; // infity value
            //Distance : the minimum cost between the source node and all the others nodes
            //initialized with infinty value
            int Width = ImageOperations.GetWidth(ImageMatrix);
            int Height = ImageOperations.GetHeight(ImageMatrix);
            int nodes_number = Width * Height;
            List<double> Distance = new List<double>();
            Distance = Enumerable.Repeat(oo, nodes_number).ToList();

            //Previous : saves the previous node that lead to the shortest path from the src node to current node 
            List<int> Previous = new List<int>();
            Previous = Enumerable.Repeat(-1, nodes_number).ToList();

            // PeriorityQueue : always return the shortest bath btween src node and specific node  
            PeriorityQueue MinimumDistances = new PeriorityQueue();
            MinimumDistances.Push(new Edge(-1, Source, 0));
            while (!MinimumDistances.IsEmpty())
            {
                // get the shortest path so far 
                Edge CurrentEdge = MinimumDistances.Top();
                MinimumDistances.Pop();
                // check if this SP is vaild (i didn't vist this node with a less cost)
                if (CurrentEdge.Weight >= Distance[CurrentEdge.To])
                    continue;
                // save the previous 
                Previous[CurrentEdge.To] = CurrentEdge.From;
                Distance[CurrentEdge.To] = CurrentEdge.Weight;
                if (CurrentEdge.To == dest) break;
                // Relaxing 
                List<Edge> neibours = GraphOperations.Get_neighbours(CurrentEdge.To, ImageMatrix);
                for (int i = 0; i < neibours.Count; i++)
                {
                    Edge HeldEdge = neibours[i];
                    // if the relaxed path cost of a neighbour node is less than  it's previous one
                    if (Distance[HeldEdge.To] > Distance[HeldEdge.From] + HeldEdge.Weight)
                    {
                        // set the relaxed cost to Distance  && pash it to the PQ
                        HeldEdge.Weight = Distance[HeldEdge.From] + HeldEdge.Weight;
                        MinimumDistances.Push(HeldEdge);
                    }
                }
            }
            return Previous;  // re turn th shortest paths from src to all nodes
        }
示例#16
0
        /// <summary>
        /// Open an image and load it into 2D array of colors (size: Height x Width)
        /// </summary>
        /// <param name="ImagePath">Image file path</param>
        /// <returns>2D array of colors</returns>
        public static RGBPixel[,] OpenImage(string ImagePath)
        {
            Bitmap original_bm = new Bitmap(ImagePath);
            int    Height      = original_bm.Height;
            int    Width       = original_bm.Width;

            RGBPixel[,] Buffer = new RGBPixel[Height, Width];

            unsafe
            {
                BitmapData bmd = original_bm.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, original_bm.PixelFormat);
                int        x, y;
                int        nWidth   = 0;
                bool       Format32 = false;
                bool       Format24 = false;
                bool       Format8  = false;

                if (original_bm.PixelFormat == PixelFormat.Format24bppRgb)
                {
                    Format24 = true;
                    nWidth   = Width * 3;
                }
                else if (original_bm.PixelFormat == PixelFormat.Format32bppArgb || original_bm.PixelFormat == PixelFormat.Format32bppRgb || original_bm.PixelFormat == PixelFormat.Format32bppPArgb)
                {
                    Format32 = true;
                    nWidth   = Width * 4;
                }
                else if (original_bm.PixelFormat == PixelFormat.Format8bppIndexed)
                {
                    Format8 = true;
                    nWidth  = Width;
                }
                int   nOffset = bmd.Stride - nWidth;
                byte *p       = (byte *)bmd.Scan0;
                for (y = 0; y < Height; y++)
                {
                    for (x = 0; x < Width; x++)
                    {
                        if (Format8)
                        {
                            Buffer[y, x].red = Buffer[y, x].green = Buffer[y, x].blue = p[0];
                            p++;
                        }
                        else
                        {
                            Buffer[y, x].red   = p[0];
                            Buffer[y, x].green = p[1];
                            Buffer[y, x].blue  = p[2];
                            if (Format24)
                            {
                                p += 3;
                            }
                            else if (Format32)
                            {
                                p += 4;
                            }
                        }
                    }
                    p += nOffset;
                }
                original_bm.UnlockBits(bmd);
            }

            return(Buffer);
        }
 /// <summary>
 /// Get the height of the image 
 /// </summary>
 /// <param name="ImageMatrix">2D array that contains the image</param>
 /// <returns>Image Height</returns>
 public static int GetHeight(RGBPixel[,] ImageMatrix)
 {
     return ImageMatrix.GetLength(0);
 }