예제 #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);
        }
예제 #2
0
        private static RGBPixel[,] CalculateHarrisCorener(RGBPixel[,] Ix2, RGBPixel[,] Iy2, RGBPixel[,] IxIy, out RGBPixel Rmax)
        {
            int Height = ImageOperations.GetHeight(Ix2);
            int Width  = ImageOperations.GetWidth(Ix2);

            RGBPixel[,] Result = new RGBPixel[Height, Width];
            double[,] A        = new double[2, 2];
            Rmax = new RGBPixel(0, 0, 0);
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    //red value
                    A[0, 0] = Ix2[i, j].red;
                    A[0, 1] = IxIy[i, j].red;
                    A[1, 0] = IxIy[i, j].red;
                    A[1, 1] = Iy2[i, j].red;
                    double detA  = Accord.Math.Matrix.Determinant(A);
                    double tracA = Accord.Math.Matrix.Trace(A);
                    Result[i, j].red = (byte)(detA - 0.01 * (tracA * tracA));
                    if (Result[i, j].red > Rmax.red)
                    {
                        Rmax.red = Result[i, j].red;
                    }
                    //green value
                    A[0, 0]            = Ix2[i, j].green;
                    A[0, 1]            = IxIy[i, j].green;
                    A[1, 0]            = IxIy[i, j].green;
                    A[1, 1]            = Iy2[i, j].green;
                    detA               = Accord.Math.Matrix.Determinant(A);
                    tracA              = Accord.Math.Matrix.Trace(A);
                    Result[i, j].green = (byte)(detA - 0.01 * (tracA * tracA));
                    if (Result[i, j].green > Rmax.green)
                    {
                        Rmax.green = Result[i, j].green;
                    }
                    //blue value
                    A[0, 0]           = Ix2[i, j].blue;
                    A[0, 1]           = IxIy[i, j].blue;
                    A[1, 0]           = IxIy[i, j].blue;
                    A[1, 1]           = Iy2[i, j].blue;
                    detA              = Accord.Math.Matrix.Determinant(A);
                    tracA             = Accord.Math.Matrix.Trace(A);
                    Result[i, j].blue = (byte)(detA - 0.01 * (tracA * tracA));
                    if (Result[i, j].blue > Rmax.blue)
                    {
                        Rmax.blue = Result[i, j].blue;
                    }
                }
            }
            return(Result);
        }
예제 #3
0
        private static RGBPixel[,] FilterProcess(RGBPixel[,] orignal, FilterType filterType, int PaddingValue)
        {
            int Height = ImageOperations.GetHeight(orignal);
            int Width  = ImageOperations.GetWidth(orignal);

            RGBPixel[,] outputImage = new RGBPixel[(Height - (PaddingValue * 2)), (Width - (PaddingValue * 2))];
            //int [,]Mask = new int[3,3];
            double[,] Mask = GenetrateMask(filterType);
            double RMax = InputImageInfo.maxValue;
            double RMin = InputImageInfo.minValue;

            for (int i = PaddingValue; i < Width - 1; i++)
            {
                for (int j = PaddingValue; j < Height - 1; j++)
                {
                    double R = 0, G = 0, B = 0;
                    int    m = i - PaddingValue;
                    int    n = j - PaddingValue;
                    for (int k = 0; k < 3; k++)
                    {
                        for (int z = 0; z < 3; z++)
                        {
                            R += orignal[n + z, m + k].red * Mask[z, k];
                            G += orignal[n + z, m + k].green * Mask[z, k];
                            B += orignal[n + z, m + k].blue * Mask[z, k];
                        }
                    }
                    if (filterType == FilterType.VerticalSobel || filterType == FilterType.HorizontalSobel)
                    {
                        if (R > 255 || G > 255 || B > 255 || R < 0 || G < 0 || B < 0)
                        {
                            outputImage[n, m] = new RGBPixel(0, 0, 0);
                        }
                        else
                        {
                            outputImage[n, m] = new RGBPixel((byte)R, (byte)G, (byte)B);
                        }
                    }
                    else
                    {
                        outputImage[n, m] = new RGBPixel((byte)R, (byte)G, (byte)B);
                    }
                }
            }
            return(outputImage);
        }
예제 #4
0
        private static RGBPixel[,] Muliply_2_Image(RGBPixel[,] ImageMatrix1, RGBPixel[,] ImageMatrix2)
        {
            int Height = ImageOperations.GetHeight(ImageMatrix1);
            int Width  = ImageOperations.GetWidth(ImageMatrix1);

            RGBPixel[,] mulResult = new RGBPixel[Height, Width];
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    mulResult[i, j].red   = (byte)(ImageMatrix1[i, j].red * ImageMatrix2[i, j].red);
                    mulResult[i, j].green = (byte)(ImageMatrix1[i, j].green * ImageMatrix2[i, j].green);
                    mulResult[i, j].blue  = (byte)(ImageMatrix1[i, j].blue * ImageMatrix2[i, j].blue);
                }
            }
            return(mulResult);
        }
예제 #5
0
        private static RGBPixel[,] Image_Padding(RGBPixel[,] orignal, int kernalsize)
        {
            int Height = ImageOperations.GetHeight(orignal);
            int Width  = ImageOperations.GetWidth(orignal);

            int paddingValue = (kernalsize / 2);

            RGBPixel[,] paddingImage = new RGBPixel[Height + (paddingValue * 2), Width + (paddingValue * 2)];
            int paddingHeight = ImageOperations.GetHeight(paddingImage);
            int paddingWidth  = ImageOperations.GetWidth(paddingImage);

            for (int i = 0; i < paddingValue; i++)
            {
                for (int j = 0; j < paddingWidth; j++)
                {
                    paddingImage[i, j] = new RGBPixel(0, 0, 0);
                }

                for (int j = 0; j < paddingWidth; j++)
                {
                    paddingImage[Height + i, j] = new RGBPixel(0, 0, 0);
                }

                for (int j = 0; j < paddingHeight; j++)
                {
                    paddingImage[j, i] = new RGBPixel(0, 0, 0);
                }

                for (int j = 0; j < paddingHeight; j++)
                {
                    paddingImage[j, Width + i] = new RGBPixel(0, 0, 0);
                }
            }

            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    paddingImage[j + paddingValue, i + paddingValue] = orignal[j, i];
                }
            }
            return(paddingImage);
        }
예제 #6
0
        private RGBPixel[,] DrawFeature(RGBPixel[,] featurePoints)
        {
            int Height = ImageOperations.GetHeight(featurePoints);
            int Width  = ImageOperations.GetWidth(featurePoints);

            RGBPixel[,] output = new RGBPixel[Height, Width];
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    output[i, j] = InputImageInfo.imgCopy[i, j];
                    if (featurePoints[i, j].red == 1)
                    {
                        output[i, j] = new RGBPixel(0, 5, 255);
                    }
                }
            }
            return(output);
        }
예제 #7
0
        public static RGBPixel[,] ContrastStretch(RGBPixel[,] ImageMatrix, double B)
        {
            int Height = ImageOperations.GetHeight(ImageMatrix);
            int Width  = ImageOperations.GetWidth(ImageMatrix);

            RGBPixel[,] output = new RGBPixel[Height, Width];
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    double R    = (double)ImageMatrix[j, i].red;
                    double RMax = InputImageInfo.maxValue;
                    double RMin = InputImageInfo.minValue;
                    byte   S    = (byte)Math.Round(Math.Pow(2, B) * ((R - RMin) / (RMax - RMin)));
                    output[j, i] = new RGBPixel(S, S, S);
                }
            }
            return(output);
        }
예제 #8
0
        public static RGBPixel[,] Apply_Threshold(RGBPixel[,] ImageMatrix, double threshold)
        {
            int Height = ImageOperations.GetHeight(ImageMatrix);
            int Width  = ImageOperations.GetWidth(ImageMatrix);

            RGBPixel[,] output = new RGBPixel[Height, Width];
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    double tmp = (double)ImageMatrix[j, i].red;
                    if (tmp >= threshold)
                    {
                        output[j, i] = new RGBPixel(255, 255, 255);
                    }
                    if (tmp < threshold)
                    {
                        output[j, i] = new RGBPixel(0, 0, 0);
                    }
                }
            }
            return(output);
        }
예제 #9
0
        private static RGBPixel[,] CalculateRresults(RGBPixel[,] R, RGBPixel Rmax, out int count)
        {
            count = 0;
            int Height = ImageOperations.GetHeight(R);
            int Width  = ImageOperations.GetWidth(R);

            RGBPixel[,] Result = new RGBPixel[Height, Width];
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    Result[i, j] = new RGBPixel(0, 0, 0);
                }
            }
            for (int i = 1; i < Height - 1; i++)
            {
                for (int j = 1; j < Width - 1; j++)
                {
                    Result[i, j] = new RGBPixel(0, 0, 0);
                    if (R[i, j].red > 0.1 * Rmax.red && R[i, j].red > R[i - 1, j - 1].red && R[i, j].red > R[i - 1, j].red && R[i, j].red > R[i - 1, j + 1].red && R[i, j].red > R[i, j - 1].red && R[i, j].red > R[i, j + 1].red && R[i, j].red > R[i + 1, j - 1].red && R[i, j].red > R[i + 1, j].red && R[i, j].red > R[i + 1, j + 1].red)
                    {
                        Result[i, j].red = 1;
                    }
                    if (R[i, j].green > 0.1 * Rmax.green && R[i, j].green > R[i - 1, j - 1].green && R[i, j].green > R[i - 1, j].green && R[i, j].green > R[i - 1, j + 1].green && R[i, j].green > R[i, j - 1].green && R[i, j].green > R[i, j + 1].green && R[i, j].green > R[i + 1, j - 1].green && R[i, j].green > R[i + 1, j].green && R[i, j].green > R[i + 1, j + 1].green)
                    {
                        Result[i, j].green = 1;
                        count++;
                    }
                    if (R[i, j].blue > 0.1 * Rmax.blue && R[i, j].blue > R[i - 1, j - 1].blue && R[i, j].blue > R[i - 1, j].blue && R[i, j].blue > R[i - 1, j + 1].blue && R[i, j].blue > R[i, j - 1].blue && R[i, j].blue > R[i, j + 1].blue && R[i, j].blue > R[i + 1, j - 1].blue && R[i, j].blue > R[i + 1, j].blue && R[i, j].blue > R[i + 1, j + 1].blue)
                    {
                        Result[i, j].blue = 1;
                    }
                }
            }
            return(Result);
        }
예제 #10
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]; // 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.
            //////////////////////////////////////////////

            return(Buffer);
        }
예제 #11
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);
        }
예제 #12
0
 public RGBPixel(RGBPixel obj)
 {
     this.red   = obj.red;
     this.green = obj.green;
     this.blue  = obj.blue;
 }