/// <summary> /// Applies histogram equalization to a given image. /// </summary> /// <param name="img"> The image of which to apply histogram equalization to </param> /// <returns> The image with applied histogram equalization </returns> public static UShortArrayAsImage ApplyHistogramEqualization(UShortArrayAsImage img) // We found formula for making the histogram equalization here: https://epochabuse.com/histogram-equalization/ { int[] histogram = MakeHistogram(img, out int blackPixelsCount); double[] normalizedHistogram = MakeNormalizedHistogram(histogram, img.PixelArray.Length - blackPixelsCount); double[] accumulativeHistogram = MakeAccumulativeHistogram(normalizedHistogram); return(new UShortArrayAsImage(CalculateResult(img.PixelArray, accumulativeHistogram))); }
/// <summary> /// Resizes the given image to the given size. /// </summary> /// <param name="uShortArrayAsImageIn"> Image to be resized </param> /// <param name="size"> Width and height of the resized image </param> /// <returns> The resized image </returns> public static UShortArrayAsImage ResizeImage(UShortArrayAsImage uShortArrayAsImageIn, int size) { var newImage = new ushort[size, size]; var image = uShortArrayAsImageIn.PixelArray; for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { newImage[y, x] = FindNearest(Map(x, 0, size, 0, image.GetLength(1)), Map(y, 0, size, 0, image.GetLength(0)), image); } } return(new UShortArrayAsImage(newImage)); }
/// <summary> /// Normalizes, crops and resizes the given UShortArrayAsImage. /// </summary> /// <param name="image">The image to be normalized</param> /// <param name="tumour">The position of the tumour</param> /// <param name="size">The desired size of the image</param> /// <returns>The normalized image as UShortArrayAsImage</returns> public static UShortArrayAsImage GetNormalizedImage(UShortArrayAsImage image, Rectangle tumour, int size) { Rectangle squareTumour = new Rectangle(); //Resize the Rectangle if (tumour.Width > tumour.Height) { squareTumour = new Rectangle(tumour.X, tumour.Y - (tumour.Width - tumour.Height) / 2, tumour.Width, tumour.Width); } else if (tumour.Width < tumour.Height || tumour.Width == tumour.Height) { squareTumour = new Rectangle(tumour.X - (tumour.Height - tumour.Width) / 2, tumour.Y, tumour.Height, tumour.Height); } return(ResizeImage(Crop(squareTumour, image), size)); }
/// <summary> /// Creates a histogram based on the given image. /// </summary> /// <param name="img"> The image </param> /// <param name="blackPixelsCount"> The amount of black pixels in the picture </param> /// <returns> The image histogram </returns> private static int[] MakeHistogram(UShortArrayAsImage img, out int blackPixelsCount) { int[] histogram = new int[UInt16.MaxValue + 1]; var pixelArray = img.PixelArray; for (int i = 0; i < img.Height; i++) { for (int j = 0; j < img.Width; j++) { histogram[pixelArray[i, j]]++; } } //Saving the amount of black pixels and setting the amount of black pixels to zero. blackPixelsCount = histogram[0]; histogram[0] = 0; return(histogram); }
/// <summary> /// Makes a crop with given location and size, out of an image. /// </summary> /// <param name="rectangle"> Location and size of the crop </param> /// <param name="image"> Image to be cropped </param> /// <returns> The cropped image </returns> public static UShortArrayAsImage Crop(Rectangle rectangle, UShortArrayAsImage image) { ushort[,] result = new ushort[rectangle.Height, rectangle.Width]; ushort[,] current = image.PixelArray; // set here - lazy evaluation for (int x = 0; x < rectangle.Width; x++) { if (rectangle.X + x < 0 || rectangle.X + x >= image.Width) { continue; } for (int y = 0; y < rectangle.Height; y++) { if (rectangle.Y + y < 0 || rectangle.Y + y >= image.Height) { continue; } result[y, x] = current[y + rectangle.Y, x + rectangle.X]; } } return(new UShortArrayAsImage(result)); }