Monday, 20 November 2017

Edge Detection Filters

 void Start_Contour_Detection()
        {
            // Copy original image to new bitmap
            Bitmap bmp = (Bitmap)Original_image.Clone();

            int Image_width = bmp.Width;
            int Image_height = bmp.Height;
           
            // Rectangle size
            Rectangle Rectangle = new Rectangle(0, 0, Image_width, Image_height);
           
            // Lock bitmap inside memory for faster processing and load bitmap data
            BitmapData bmp_Data = bmp.LockBits(Rectangle, ImageLockMode.ReadWrite, bmp.PixelFormat);
           
           
            // Load adress of the first byte of the bitmap,
            // it is pointer to the adress
            IntPtr bmp_First_byte_adress = bmp_Data.Scan0;

            int Number_of_pixels = Image_width * Image_height;
            int Number_of_bytes  = Number_of_pixels * 3;

            int Exact_number_of_bytes_in_row  = bmp_Data.Stride;
            int Necessary_number_of_bytes = Image_width*3;
            //
            int Number_of_alignment_bytes =  Exact_number_of_bytes_in_row - Necessary_number_of_bytes;
            //
            // Total count of bytes necesary for all image pixels
            Number_of_bytes += Image_height * Number_of_alignment_bytes;
            //
            // One dimensional matrix for memorizing bitmap
            // values of RGB components of color of pixels
            byte[] bmp_RGB_values = new byte[Number_of_bytes];
           
           
            // Copy values of RGB components of pixel color from bitmap to matrix
            Marshal.Copy(bmp_First_byte_adress, bmp_RGB_values, 0, Number_of_bytes);
           
           
           
            // Two dimensional matrix for memorizing bitmap
            // values of RGB components of color of pixels
            byte [,,] RGB = new byte[Image_width,Image_height,3];
           
            // Matrix for memorizing values of brightness of pixels
            float [,] Brightness = new float[Image_width,Image_height];
           
            // Byte counter inside one dimenzional matrix
            int bmp_k = 0;
           
           
            // Copy bitmap values of RGB components of color of pixels,
            // from one dimenzional to two dimenzional matrix
            // and fill matrix Brightness with values of brightness of pixels
            //
            // NOTICE :
            // When loading bitmap data
            // BitmapData bmp_Data = bmp.LockBits(Rectangle, ImageLockMode.ReadWrite, bmp.PixelFormat); ,
            // values of RGB components of color of pixels are returned in opposite direction
            // RGB -> BGR
            //
            for (int i=0;i<Image_height;i++)
            {
                for(int j=0;j<Image_width;j++)
                {
                    // Value of R component of pixel color
                    RGB[j,i,0] = bmp_RGB_values[bmp_k+2];
                   
                    // Value of G component of pixel color
                    RGB[j,i,1] = bmp_RGB_values[bmp_k+1];
                   
                    // Value of B component of pixel color
                    RGB[j,i,2] = bmp_RGB_values[bmp_k+0];
                   
                    // Value of pixel brightness
                    Brightness[j,i] = Color.FromArgb
                        (
                            bmp_RGB_values[bmp_k+2],
                            bmp_RGB_values[bmp_k+1],
                            bmp_RGB_values[bmp_k+0]
                        ).GetBrightness();
                   
                    bmp_k+=3;
                }
               
                bmp_k+= Number_of_alignment_bytes;
            }


            // Load lower and upper limit of the brightness
            float lower_limit  = (float) Lower_Brightness_Limit.Value;
            float upper_limit  = (float) Upper_Brightness_Limit.Value;
           
            // Maximum found value for the difference in brightness
            // between the opposing pixels
            float mfd = 0;
           
            for(int i=1;i<Image_height-1;i++)
            {
                for(int j=1;j<Image_width-1;j++)
                {
                   
                    //
                    mfd = Math.Abs(Brightness[j-1,i-1]-Brightness[j+1,i+1]);
                   
                    //
                    if(mfd<Math.Abs(Brightness[j-1,i+1]-Brightness[j+1,i-1]))
                        mfd=Math.Abs(Brightness[j-1,i+1]-Brightness[j+1,i-1]);
                   
                    //
                    if(mfd<Math.Abs(Brightness[j,i+1]-Brightness[j,i-1]))
                        mfd=Math.Abs(Brightness[j,i+1]-Brightness[j,i-1]);
                   
                    //
                    if(mfd<Math.Abs(Brightness[j-1,i]-Brightness[j+1,i]))
                        mfd=Math.Abs(Brightness[j-1,i]-Brightness[j+1,i]);
                   
                    //
                    if(Invert_Edge_Color.Checked)
                    {
                        if(mfd<lower_limit)
                        {
                            RGB[j,i,0] = (byte) 255;
                            RGB[j,i,1] = (byte) 255;
                            RGB[j,i,2] = (byte) 255;
                        }
                        else if(mfd>upper_limit)
                        {
                            RGB[j,i,0] = (byte) 0;
                            RGB[j,i,1] = (byte) 0;
                            RGB[j,i,2] = (byte) 0;
                        }
                    }
                    else
                    {
                        if(mfd<lower_limit)
                        {
                            RGB[j,i,0] = (byte) 0;
                            RGB[j,i,1] = (byte) 0;
                            RGB[j,i,2] = (byte) 0;
                        }
                        else if(mfd>upper_limit)
                        {
                            RGB[j,i,0] = (byte) 255;
                            RGB[j,i,1] = (byte) 255;
                            RGB[j,i,2] = (byte) 255;
                        }
                    }
                   
                }
            }
           
           
            if(Black_White.Checked)
            {
                for(int i=1;i<Image_height-1;i++)
                {
                    for(int j=1;j<Image_width-1;j++)
                    {
                        if(Invert_Edge_Color.Checked)
                        {
                            if(RGB[j,i,0] < 255 || RGB[j,i,1] < 255 || RGB[j,i,2] < 255)
                                RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] = (byte) 0;
                        }
                        else
                        {
                            if(RGB[j,i,0] > 0 || RGB[j,i,1] > 0 || RGB[j,i,2] > 0)
                                RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] = (byte) 255;
                        }
                    }
                }
            }
           
           
            if(Gray_Scale.Checked)
            {
                for(int i=1;i<Image_height-1;i++)
                {
                    for(int j=1;j<Image_width-1;j++)
                    {
                        RGB[j,i,0] = RGB[j,i,1] = RGB[j,i,2] =
                            (byte)
                            (
                                (0.299*RGB[j,i,0]) +
                                (0.587*RGB[j,i,1]) +
                                (0.114*RGB[j,i,2])
                            );
                    }
                }
            }
           
           
            // Byte counter inside one dimenzional matrix
            bmp_k = 0;
           
            // Copy new bitmap values of RGB components of color of pixels,
            // from two dimenzional to one dimenzional matrix
            for (int i=0;i<Image_height;i++)
            {
                for(int j=0;j<Image_width;j++)
                {
                    // Value of R component of pixel color
                    bmp_RGB_values[bmp_k+2] = RGB[j,i,0];
                   
                    // Value of G component of pixel color
                    bmp_RGB_values[bmp_k+1] = RGB[j,i,1];
                   
                    // Value of B component of pixel color
                    bmp_RGB_values[bmp_k+0] = RGB[j,i,2];
                   
                    bmp_k+=3;
                }
               
                bmp_k+=Number_of_alignment_bytes;
            }
           
            // Copy new values of RGB components of pixel color from matrix back to bitmap
            Marshal.Copy(bmp_RGB_values, 0, bmp_First_byte_adress, Number_of_bytes);
           
            // Unlock bitmap inside memory
            bmp.UnlockBits(bmp_Data);
           
            // Show the processed image
            Image_2.Image = bmp;
        }

No comments:

Post a Comment