public FrmMorphology(MorphologyType morphologyType) { InitializeComponent(); mMorphologyType = mArgs.FuntionType = morphologyType; InitFuntion(); }
private Bitmap ErodeDilate(Bitmap sourceBitmap, int[,] SE, MorphologyType method) { var result = new Bitmap(sourceBitmap); int offset = SE.GetLength(0); int offsetCenter = (offset - 1) / 2; int morphResetValue = (method == MorphologyType.Erosion ? 255 : 0); for (int y = 0; y < sourceBitmap.Height; y++) { for (int x = 0; x < sourceBitmap.Width; x++) { var newColor = morphResetValue; for (int ySE = -offsetCenter; ySE <= offsetCenter; ySE++) { for (int xSE = -offsetCenter; xSE <= offsetCenter; xSE++) { if ( SE[ySE + offsetCenter, xSE + offsetCenter] != 1 || x + xSE < 0 || x + xSE >= sourceBitmap.Width || y + ySE < 0 || y + ySE >= sourceBitmap.Height ) { continue; } newColor = method == MorphologyType.Erosion ? Math.Min(newColor, sourceBitmap.GetPixel(x + xSE, y + ySE).R) : Math.Max(newColor, sourceBitmap.GetPixel(x + xSE, y + ySE).R); } } result.SetPixel(x, y, Color.FromArgb(newColor, newColor, newColor)); } } return(result); }
public static Bitmap DilateAndErodeFilter(this Bitmap sourceBitmap, int matrixSize, MorphologyType morphType, bool applyBlue = true, bool applyGreen = true, bool applyRed = true) { BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height]; byte[] resultBuffer = new byte[sourceData.Stride * sourceData.Height]; Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); sourceBitmap.UnlockBits(sourceData); int filterOffset = (matrixSize - 1) / 2; int calcOffset = 0; int byteOffset = 0; byte blue = 0; byte green = 0; byte red = 0; byte morphResetValue = 0; if (morphType == MorphologyType.Erosion) { morphResetValue = 255; } for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++) { for (int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++) { byteOffset = offsetY * sourceData.Stride + offsetX * 4; blue = morphResetValue; green = morphResetValue; red = morphResetValue; if (morphType == MorphologyType.Dilation) { for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); if (pixelBuffer[calcOffset] > blue) { blue = pixelBuffer[calcOffset]; } if (pixelBuffer[calcOffset + 1] > green) { green = pixelBuffer[calcOffset + 1]; } if (pixelBuffer[calcOffset + 2] > red) { red = pixelBuffer[calcOffset + 2]; } } } } else if (morphType == MorphologyType.Erosion) { for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); if (pixelBuffer[calcOffset] < blue) { blue = pixelBuffer[calcOffset]; } if (pixelBuffer[calcOffset + 1] < green) { green = pixelBuffer[calcOffset + 1]; } if (pixelBuffer[calcOffset + 2] < red) { red = pixelBuffer[calcOffset + 2]; } } } } if (applyBlue == false) { blue = pixelBuffer[byteOffset]; } if (applyGreen == false) { green = pixelBuffer[byteOffset + 1]; } if (applyRed == false) { red = pixelBuffer[byteOffset + 2]; } resultBuffer[byteOffset] = blue; resultBuffer[byteOffset + 1] = green; resultBuffer[byteOffset + 2] = red; resultBuffer[byteOffset + 3] = 255; } } Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); resultBitmap.UnlockBits(resultData); return resultBitmap; }
/// <summary> /// Dilate And Erode Filter /// </summary> /// <param name="sourceBitmap">Set source Bitmap</param> /// <param name="matrixSize">Set matrix size</param> /// <param name="morphType">Set Morphology Type</param> /// <param name="applyBlue">Apply Blue</param> /// <param name="applyGreen">Apply Green</param> /// <param name="applyRed">Apply Red</param> /// <param name="edgeType">Morphology Edge Type</param> /// <returns></returns> public static System.Drawing.Bitmap DilateAndErodeFilter(this System.Drawing.Bitmap sourceBitmap, int matrixSize, MorphologyType morphType, bool applyBlue = true, bool applyGreen = true, bool applyRed = true, MorphologyEdgeType edgeType = MorphologyEdgeType.None) { BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height]; byte[] resultBuffer = new byte[sourceData.Stride * sourceData.Height]; Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); sourceBitmap.UnlockBits(sourceData); int filterOffset = (matrixSize - 1) / 2; int calcOffset = 0; int byteOffset = 0; int blue = 0; int green = 0; int red = 0; byte morphResetValue = 0; if (morphType == MorphologyType.Erosion) { morphResetValue = 255; } for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++) { for (int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++) { byteOffset = offsetY * sourceData.Stride + offsetX * 4; blue = morphResetValue; green = morphResetValue; red = morphResetValue; if (morphType == MorphologyType.Dilation) { for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); if (pixelBuffer[calcOffset] > blue) { blue = pixelBuffer[calcOffset]; } if (pixelBuffer[calcOffset + 1] > green) { green = pixelBuffer[calcOffset + 1]; } if (pixelBuffer[calcOffset + 2] > red) { red = pixelBuffer[calcOffset + 2]; } } } } else if (morphType == MorphologyType.Erosion) { for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); if (pixelBuffer[calcOffset] < blue) { blue = pixelBuffer[calcOffset]; } if (pixelBuffer[calcOffset + 1] < green) { green = pixelBuffer[calcOffset + 1]; } if (pixelBuffer[calcOffset + 2] < red) { red = pixelBuffer[calcOffset + 2]; } } } } if (applyBlue == false) { blue = pixelBuffer[byteOffset]; } if (applyGreen == false) { green = pixelBuffer[byteOffset + 1]; } if (applyRed == false) { red = pixelBuffer[byteOffset + 2]; } if (edgeType == MorphologyEdgeType.EdgeDetection || edgeType == MorphologyEdgeType.SharpenEdgeDetection) { if (morphType == MorphologyType.Dilation) { blue = blue - pixelBuffer[byteOffset]; green = green - pixelBuffer[byteOffset + 1]; red = red - pixelBuffer[byteOffset + 2]; } else if (morphType == MorphologyType.Erosion) { blue = pixelBuffer[byteOffset] - blue; green = pixelBuffer[byteOffset + 1] - green; red = pixelBuffer[byteOffset + 2] - red; } if (edgeType == MorphologyEdgeType.SharpenEdgeDetection) { blue += pixelBuffer[byteOffset]; green += pixelBuffer[byteOffset + 1]; red += pixelBuffer[byteOffset + 2]; } } blue = (blue > 255 ? 255 : (blue < 0 ? 0 : blue)); green = (green > 255 ? 255 : (green < 0 ? 0 : green)); red = (red > 255 ? 255 : (red < 0 ? 0 : red)); resultBuffer[byteOffset] = (byte)blue; resultBuffer[byteOffset + 1] = (byte)green; resultBuffer[byteOffset + 2] = (byte)red; resultBuffer[byteOffset + 3] = 255; } } System.Drawing.Bitmap resultBitmap = new System.Drawing.Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); resultBitmap.UnlockBits(resultData); return(resultBitmap); }
/// <summary> /// 膨胀和腐蚀 /// </summary> /// <param name="sourceBitmap"></param> /// <param name="matrixSize"></param> /// <param name="morphType"></param> /// <param name="applyBlue"></param> /// <param name="applyGreen"></param> /// <param name="applyRed"></param> /// <returns></returns> public static Bitmap DilateAndErodeFilter(this Bitmap sourceBitmap, int matrixSize, MorphologyType morphType, bool applyBlue = true, bool applyGreen = true, bool applyRed = true) { BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height]; byte[] resultBuffer = new byte[sourceData.Stride * sourceData.Height]; Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); sourceBitmap.UnlockBits(sourceData); int filterOffset = (matrixSize - 1) / 2; int calcOffset = 0; int byteOffset = 0; byte blue = 0; byte green = 0; byte red = 0; byte morphResetValue = 0; if (morphType == MorphologyType.Erosion) { morphResetValue = 255; } for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++) { for (int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++) { byteOffset = offsetY * sourceData.Stride + offsetX * 4; blue = morphResetValue; green = morphResetValue; red = morphResetValue; if (morphType == MorphologyType.Dilation) { for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); if (pixelBuffer[calcOffset] > blue) { blue = pixelBuffer[calcOffset]; } if (pixelBuffer[calcOffset + 1] > green) { green = pixelBuffer[calcOffset + 1]; } if (pixelBuffer[calcOffset + 2] > red) { red = pixelBuffer[calcOffset + 2]; } } } } else if (morphType == MorphologyType.Erosion) { for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); if (pixelBuffer[calcOffset] < blue) { blue = pixelBuffer[calcOffset]; } if (pixelBuffer[calcOffset + 1] < green) { green = pixelBuffer[calcOffset + 1]; } if (pixelBuffer[calcOffset + 2] < red) { red = pixelBuffer[calcOffset + 2]; } } } } if (applyBlue == false) { blue = pixelBuffer[byteOffset]; } if (applyGreen == false) { green = pixelBuffer[byteOffset + 1]; } if (applyRed == false) { red = pixelBuffer[byteOffset + 2]; } resultBuffer[byteOffset] = blue; resultBuffer[byteOffset + 1] = green; resultBuffer[byteOffset + 2] = red; resultBuffer[byteOffset + 3] = 255; } } Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); resultBitmap.UnlockBits(resultData); return(resultBitmap); }
/// <summary> /// Dilate the and erode filter. /// </summary> /// <param name="sourceBitmap">The source bitmap.</param> /// <param name="matrixSize">Size of the matrix.</param> /// <param name="morphType">Type of the morph.</param> /// <param name="applyBlue">if set to <c>true</c> [apply blue].</param> /// <param name="applyGreen">if set to <c>true</c> [apply green].</param> /// <param name="applyRed">if set to <c>true</c> [apply red].</param> /// <param name="edgeType">Type of the edge.</param> /// <returns>Bitmap.</returns> public Bitmap DilateAndErodeFilter(Bitmap sourceBitmap, int matrixSize, MorphologyType morphType, bool applyBlue = true, bool applyGreen = true, bool applyRed = true, MorphologyEdgeType edgeType = MorphologyEdgeType.None) { try { BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height]; byte[] resultBuffer = new byte[sourceData.Stride * sourceData.Height]; Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length); sourceBitmap.UnlockBits(sourceData); int filterOffset = (matrixSize - 1) / 2; int calcOffset = 0; int byteOffset = 0; int blue = 0; int green = 0; int red = 0; byte morphResetValue = 0; if (morphType == MorphologyType.Erosion) { morphResetValue = 255; } for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++) { for (int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++) { byteOffset = offsetY * sourceData.Stride + offsetX * 4; blue = morphResetValue; green = morphResetValue; red = morphResetValue; if (morphType == MorphologyType.Dilation) { for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); if (pixelBuffer[calcOffset] > blue) { blue = pixelBuffer[calcOffset]; } if (pixelBuffer[calcOffset + 1] > green) { green = pixelBuffer[calcOffset + 1]; } if (pixelBuffer[calcOffset + 2] > red) { red = pixelBuffer[calcOffset + 2]; } } } } else if (morphType == MorphologyType.Erosion) { for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride); if (pixelBuffer[calcOffset] < blue) { blue = pixelBuffer[calcOffset]; } if (pixelBuffer[calcOffset + 1] < green) { green = pixelBuffer[calcOffset + 1]; } if (pixelBuffer[calcOffset + 2] < red) { red = pixelBuffer[calcOffset + 2]; } } } } if (applyBlue == false) { blue = pixelBuffer[byteOffset]; } if (applyGreen == false) { green = pixelBuffer[byteOffset + 1]; } if (applyRed == false) { red = pixelBuffer[byteOffset + 2]; } if (edgeType == MorphologyEdgeType.Edge || edgeType == MorphologyEdgeType.EdgeSharpen) { if (morphType == MorphologyType.Dilation) { blue = blue - pixelBuffer[byteOffset]; green = green - pixelBuffer[byteOffset + 1]; red = red - pixelBuffer[byteOffset + 2]; } else if (morphType == MorphologyType.Erosion) { blue = pixelBuffer[byteOffset] - blue; green = pixelBuffer[byteOffset + 1] - green; red = pixelBuffer[byteOffset + 2] - red; } if (edgeType == MorphologyEdgeType.EdgeSharpen) { blue += pixelBuffer[byteOffset]; green += pixelBuffer[byteOffset + 1]; red += pixelBuffer[byteOffset + 2]; } } blue = (blue > 255 ? 255 : (blue < 0 ? 0 : blue)); green = (green > 255 ? 255 : (green < 0 ? 0 : green)); red = (red > 255 ? 255 : (red < 0 ? 0 : red)); resultBuffer[byteOffset] = (byte)blue; resultBuffer[byteOffset + 1] = (byte)green; resultBuffer[byteOffset + 2] = (byte)red; resultBuffer[byteOffset + 3] = 255; } } Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); resultBitmap.UnlockBits(resultData); return resultBitmap; } catch (Exception ex) { return new Bitmap(ImageFactory.Draw(ex.Message)); } }
private Bitmap DilateAndErodeFilter(MorphologyType morphType, int matrixSize) {// Размеры изображения int width = bmp.Width; int height = bmp.Height; //Создание массивов байтов для хранения информации о пикселях изображения bool[] resultBw = (bool[])binIm.Clone(); byte[] resultBuffer = new byte[width * height * 4]; //центральный пиксель смещен от границы ядра int filterOffset = (matrixSize - 1) / 2; int calcOffset = 0; int byteOffset = 0; bool res; if (morphType == MorphologyType.Dilation) { for (int offsetY = filterOffset; offsetY < height - filterOffset; offsetY++) { for (int offsetX = filterOffset; offsetX < width - filterOffset; offsetX++) { //положение пикселя центра ядра byteOffset = offsetY * width + offsetX; res = true; // Применение дилатации for (int filterY = -filterOffset; filterY <= filterOffset && res; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = (offsetY + filterY) * width + offsetX + filterX; if (!binIm[calcOffset]) { res = false; break; } } } resultBw[byteOffset] = res; //Запись обработанных данных во второй массив resultBuffer[byteOffset * 4] = res ? (byte)255 : (byte)0; resultBuffer[byteOffset * 4 + 1] = resultBuffer[byteOffset * 4]; resultBuffer[byteOffset * 4 + 2] = resultBuffer[byteOffset * 4]; resultBuffer[byteOffset * 4 + 3] = 255; } } } else if (morphType == MorphologyType.Erosion) { for (int offsetY = filterOffset; offsetY < height - filterOffset; offsetY++) { for (int offsetX = filterOffset; offsetX < width - filterOffset; offsetX++) { byteOffset = offsetY * width + offsetX; // положение пикселя центра ядра res = false; // вычисления ядра for (int filterY = -filterOffset; filterY <= filterOffset && !res; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) { calcOffset = (offsetY + filterY) * width + offsetX + filterX; if (binIm[calcOffset]) { res = true; break; } } } resultBw[byteOffset] = resultBw[byteOffset] ? resultBw[byteOffset] : res; //установим новые данные в другом массиве байтов resultBuffer[byteOffset * 4] = resultBw[byteOffset] ? (byte)255 : (byte)0; resultBuffer[byteOffset * 4 + 1] = resultBuffer[byteOffset * 4]; resultBuffer[byteOffset * 4 + 2] = resultBuffer[byteOffset * 4]; resultBuffer[byteOffset * 4 + 3] = 255; } } } binIm = resultBw; // Создаём новое изображение, которое будет содержать обработанные данные Bitmap resultBitmap = new Bitmap(width, height); BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); // Копирование данных изображения в массивов байтов Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); // Разблокируем бит из системной памяти так как у нас есть вся необходимая информация в массиве resultBitmap.UnlockBits(resultData); return(resultBitmap); }