/// <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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
/// <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); }
/// <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 RGBPixel(RGBPixel obj) { this.red = obj.red; this.green = obj.green; this.blue = obj.blue; }