Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public static class OpeningClosingTools
- {
- public static byte[,] MakeStructuralElement(int linelen, int degrees)
- {
- if (degrees > 180)
- degrees = degrees - 180;
- double alpha = degrees * Math.PI / 180;
- double ray = Math.Ceiling(((double)linelen - 1) / 2);
- int columns = (int)(Math.Ceiling(linelen * Math.Cos(alpha))) + 1;
- int rows = (int)(Math.Ceiling(linelen * Math.Sin(alpha))) + 1;
- if (columns < 0)
- columns = (columns - 1) * (-1);
- if (rows < 0)
- rows = (rows - 1) * (-1);
- if (degrees > 90)
- columns++;
- if (columns % 2 == 0)
- columns--;
- if (rows % 2 == 0)
- rows--;
- byte[,] line = new byte[rows, columns];
- double a;
- double counter = ((rows - 1) / 2);
- double denominator = ((columns - 1) / 2);
- a = counter / denominator;
- if (double.IsInfinity(a))
- {
- for (int i = 0; i < rows; i++)
- {
- line[i, 0] = 1;
- }
- }
- else
- {
- for (int i = 0; i < columns; i++)
- {
- double y = (rows - 1) - (a * i);
- if (i < ((columns - 1) / 2))
- {
- y = Math.Ceiling(y);
- }
- else if (i > ((columns - 1) / 2))
- {
- y = Math.Floor(y);
- }
- line[(int)y, i] = 1;
- }
- }
- if (degrees > 90)
- {
- for (int i = 0; i < rows; i++)
- {
- for (int j = 0; j < columns; j++)
- {
- if ((i > (rows - 1) / 2) && (j > (columns - 1) / 2))
- break;
- if (line[i, j] == 1)
- {
- int newindex = (columns - 1) - j;
- line[i, j] = 0;
- line[i, newindex] = 1;
- }
- }
- }
- }
- return line;
- }
- public static Bitmap DilateAndErodeFilter(Bitmap sourceBitmap, byte[,] structuralElement, MorphologyType morphType)
- {
- //Create image dimension variables for convenience
- int width = sourceBitmap.Width;
- int height = sourceBitmap.Height;
- //Lock bits to system memory for fast processing
- Rectangle canvas = new Rectangle(0, 0, width, height);
- BitmapData srcData = sourceBitmap.LockBits(canvas, ImageLockMode.ReadOnly,
- PixelFormat.Format32bppArgb);
- int stride = srcData.Stride;
- int bytes = stride * srcData.Height;
- //Create byte arrays that will hold all pixel data, one for processing, one for output
- byte[] pixelBuffer = new byte[bytes];
- byte[] resultBuffer = new byte[bytes];
- //Write pixel data to array meant for processing
- Marshal.Copy(srcData.Scan0, pixelBuffer, 0, bytes);
- sourceBitmap.UnlockBits(srcData);
- int rows = structuralElement.GetLength(0);
- int columns = structuralElement.GetLength(1);
- int horizontalOffset = (rows - 1) / 2;
- int verticalOffset = (columns - 1) / 2;
- int calcOffset = 0;
- int byteOffset = 0;
- for (int x = horizontalOffset; x < width - horizontalOffset; x++)
- {
- for (int y = verticalOffset; y < height - verticalOffset; y++)
- {
- byte value = 0;
- if (morphType == MorphologyType.Erosion)
- value = 255;
- byteOffset = y * stride + x * 4;
- for (int xMatrix = 0; xMatrix < rows; xMatrix++)
- {
- for (int yMatrix = 0; yMatrix < columns; yMatrix++)
- {
- if (structuralElement[xMatrix, yMatrix] == 1)
- {
- calcOffset = byteOffset + xMatrix * stride + yMatrix * 4;
- if (calcOffset >= bytes)
- {
- continue;
- }
- if (morphType == MorphologyType.Dilation)
- {
- value = Math.Max(value, pixelBuffer[calcOffset]);
- }
- else if (morphType == MorphologyType.Erosion)
- {
- value = Math.Min(value, pixelBuffer[calcOffset]);
- }
- }
- else
- {
- continue;
- }
- }
- }
- //Write processed data into the second array
- resultBuffer[byteOffset] = value;
- resultBuffer[byteOffset + 1] = value;
- resultBuffer[byteOffset + 2] = value;
- resultBuffer[byteOffset + 3] = 255;
- }
- }
- //Create output bitmap of this function
- Bitmap rsltImg = new Bitmap(width, height);
- BitmapData rsltData = rsltImg.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
- //Write processed data into bitmap form
- Marshal.Copy(resultBuffer, 0, rsltData.Scan0, bytes);
- rsltImg.UnlockBits(rsltData);
- return rsltImg;
- }
- public static Bitmap OpenMorphologyFilter(this Bitmap sourceBitmap,
- byte[,] structuralElement)
- {
- Bitmap resultBitmap = DilateAndErodeFilter(sourceBitmap, structuralElement, MorphologyType.Erosion);
- return DilateAndErodeFilter(resultBitmap, structuralElement, MorphologyType.Dilation);
- }
- public static Bitmap CloseMorphologyFilter(this Bitmap sourceBitmap,
- byte[,] structuralElement)
- {
- Bitmap resultBitmap = DilateAndErodeFilter(sourceBitmap, structuralElement, MorphologyType.Dilation);
- return DilateAndErodeFilter(resultBitmap, structuralElement, MorphologyType.Erosion);
- }
- public enum MorphologyType
- {
- Dilation,
- Erosion
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement