private static List<Point> FindNeighbours(Image image, Point p) { List<Point> neighbours = new List<Point>(); //West if (!(p.X - 1 < 0)) { if (image.GetPixelColor(p.X - 1, p.Y) == Image.Black) neighbours.Add(new Point(p.X - 1, p.Y)); } //North if (!(p.Y - 1 < 0)) { if (image.GetPixelColor(p.X, p.Y - 1) == Image.Black) neighbours.Add(new Point(p.X, p.Y - 1)); } //East if (!(p.X + 1 >= image.Size.Width)) { if (image.GetPixelColor(p.X + 1, p.Y) == Image.Black) neighbours.Add(new Point(p.X + 1, p.Y)); } //South if (!(p.Y + 1 >= image.Size.Height)) { if (image.GetPixelColor(p.X, p.Y + 1) == Image.Black) neighbours.Add(new Point(p.X, p.Y + 1)); } return neighbours; }
private static int CalculateNewPixelValue(int x, int y, int layer, Image image) { int[] values = new int[8]; List<Point> neighbours = FindNeighbours(image, layer, new Point(x, y)); int counter = 0; foreach(Point p in neighbours) { if(image.GetPixelColor(p.X, p.Y) == Image.Black) counter += 1; } return (counter >= neighbours.Count/2) ? Image.Black : Image.White; }
public void ApplyKernel(Image image, Kernel kernel) { int[,] currentPixels = image.GetPixels(); int[,] newPixels = new int[image.Size.Width, image.Size.Height]; //kernel information int kernelWidth = kernel.kernelSize.Width; int kernelHeight = kernel.kernelSize.Height; int middelPixelIndexWidth = kernelWidth / 2; int middelPixelIndexHeight = kernelHeight / 2; //Loop through the image for (int x = 0; x < image.Size.Width; x++) { for (int y = 0; y < image.Size.Height; y++) { newPixels[x, y] = currentPixels[x, y];//current quickfix untill the proper kernel-out-of-bounce-code is implemented. This line adds an initial value of the current pixel, based on the original image. //Determin kernel's position, based on current pixel int kernelStartPositionX = x - middelPixelIndexWidth; int kernelStartPositionY = y - middelPixelIndexHeight; //variable to store the new values that are being calculated double ColourValue = 0; //checks if the kernel isn't out of bounce if (kernelStartPositionX < 0 || kernelStartPositionY < 0) continue; if (kernelStartPositionX + kernel.kernelSize.Width > image.Size.Width || kernelStartPositionY + kernel.kernelSize.Height > image.Size.Height) continue; //todo: change code so it will do something other then just 'not'changing the pixel, when the kernel is ou tof bounce //Loop through the kernel for (int k = 0; k < kernelWidth; k++) { for (int l = 0; l < kernelHeight; l++) { //Get the current kernel's position's color-value int pixelColor = image.GetPixelColor(kernelStartPositionX + k, kernelStartPositionY + l); ColourValue += (pixelColor * (kernel.GetValue(l, k) * kernel.multiplier)); //calculates the value that has to be added, based on the kernel value and multiplier } } newPixels[x, y] = (int)(ColourValue); //sets new value } } image.SetPixels(newPixels); }
/// <summary> /// Calculate the Perimeter (the total length of the object boundary) /// </summary> /// <param name="image"></param> /// <returns></returns> public static float Calculate(Image image) { float perimeter = 0;//Variable that holds our current length Point p = Toolbox.FindFirstPixel(image); //find the first pixel so we can loop through the edge/pixels of our object if (image.GetPixelColor(p.X, p.Y) == Image.White) return 0;//In case we found an empty starting point int[,] visited = new int[image.Size.Width, image.Size.Height];//array that represents visited pixels Stack<Point> toVisit = new Stack<Point>(); //stack with points that we still have to visit toVisit.Push(p); //While we still have to visit pixels: //Loop through those pixels. If they are near the edge, add a value to our perimeter and check if it has neighbours that we still have to visit. while (toVisit.Count > 0) { Point point = toVisit.Pop(); if (HasVisited(ref visited, point)) //did we already visit this pixel? { continue; } Visit(ref visited, point); //mark this pixel as visited List<Point> neighbours = FindNeighbours(image, point); //find black neighbours if (neighbours.Count >= 4) continue;//If this pixel is surrounded by black pixels, ignore it foreach (Point n in neighbours) { if (!HasVisited(ref visited, n)) { toVisit.Push(n); //push neighbours only if we havent visit them yet } } perimeter += (4 - neighbours.Count); //4 possible neighbours, but the list contains the black ones, so this will add the white ones. } return perimeter; }
/// <summary> /// Returns a list of pixels that represent the border of an item /// </summary> /// <param name="image">target item</param> /// <returns>list of points that represent the border of the item</returns> public static List<Point> OuterPoints(Image image) { List<Point> coordinates = new List<Point>(); Point p = Toolbox.FindFirstPixel(image); if (image.GetPixelColor(p.X, p.Y) == Image.White) return coordinates;//In case we found an empty starting point int[,] visited = new int[image.Size.Width, image.Size.Height]; Stack<Point> toVisit = new Stack<Point>(); toVisit.Push(p); while (toVisit.Count > 0) { Point point = toVisit.Pop(); if (HasVisited(ref visited, point)) { continue; } Visit(ref visited, point); coordinates.Add(point); //ObjectOuterPixels.SaveOuterPixelsAsImage(coordinates, image.Size);//uncomment this to view each step :D List<Point> neighbours = FindNeighbours(image, point); //find black neighbours if (neighbours.Count >= 8) continue; foreach (Point n in neighbours) { if (!HasVisited(ref visited, n)) { toVisit.Push(n); } } } //ObjectOuterPixels.SaveOuterPixelsAsImage(coordinates, image.Size);//uncomment this to view result return coordinates; }