public static Bitmap EdgeDetectQuick(Bitmap b) { ConvMatrix m = new ConvMatrix(); m.TopLeft = m.TopMid = m.TopRight = -1; m.MidLeft = m.Pixel = m.MidRight = 0; m.BottomLeft = m.BottomMid = m.BottomRight = 1; m.Offset = 127; return(BitmapFilter.Conv3x3(b, m)); }
public static Bitmap EdgeDetectConvolution(Bitmap b, EdgeDetectionMethod nType, byte nThreshold) { ConvMatrix m = new ConvMatrix(); // First we need to keep a copy of the original Bitmap. using (Bitmap bTemp = (Bitmap)b.Clone()) { try { switch (nType) { case EdgeDetectionMethod.Sobel: m.SetAll(0); m.TopLeft = m.BottomLeft = 1; m.TopRight = m.BottomRight = -1; m.MidLeft = 2; m.MidRight = -2; m.Offset = 0; break; case EdgeDetectionMethod.Prewitt: m.SetAll(0); m.TopLeft = m.MidLeft = m.BottomLeft = -1; m.TopRight = m.MidRight = m.BottomRight = 1; m.Offset = 0; break; case EdgeDetectionMethod.Kirsh: m.SetAll(-3); m.Pixel = 0; m.TopLeft = m.MidLeft = m.BottomLeft = 5; m.Offset = 0; break; } BitmapFilter.Conv3x3(b, m); switch (nType) { case EdgeDetectionMethod.Sobel: m.SetAll(0); m.TopLeft = m.TopRight = 1; m.BottomLeft = m.BottomRight = -1; m.TopMid = 2; m.BottomMid = -2; m.Offset = 0; break; case EdgeDetectionMethod.Prewitt: m.SetAll(0); m.BottomLeft = m.BottomMid = m.BottomRight = -1; m.TopLeft = m.TopMid = m.TopRight = 1; m.Offset = 0; break; case EdgeDetectionMethod.Kirsh: m.SetAll(-3); m.Pixel = 0; m.BottomLeft = m.BottomMid = m.BottomRight = 5; m.Offset = 0; break; } BitmapFilter.Conv3x3(bTemp, m); } catch { throw; } // GDI+ lies - return format is BGR, not RGB. BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData bmpData2 = bTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); try { int stride = bmpData.Stride; unsafe { byte *p = (byte *)(void *)bmpData.Scan0; byte *p2 = (byte *)(void *)bmpData2.Scan0; int nOffset = stride - b.Width * 3; int nWidth = b.Width * 3; int nPixel = 0; for (int y = 0; y < b.Height; ++y) { for (int x = 0; x < nWidth; ++x) { nPixel = (int)System.Math.Sqrt((p[0] * p[0]) + (p2[0] * p2[0])); if (nPixel < nThreshold) { nPixel = nThreshold; } if (nPixel > 255) { nPixel = 255; } p[0] = (byte)nPixel; ++p; ++p2; } p += nOffset; p2 += nOffset; } } } catch { throw; } finally { b.UnlockBits(bmpData); bTemp.UnlockBits(bmpData2); } } return(b); }
public static Bitmap Conv3x3(Bitmap b, ConvMatrix m) { // Avoid divide by zero errors. if (m.Factor == 0) { throw new ArgumentException("Conversion matrix factor must be greater than zero.", "m"); } Bitmap bmpDest = new Bitmap(b.Width, b.Height); // GDI+ lies - the return format is BGR, not RGB (stupid little-endian) BitmapData bitData = bmpDest.LockBits(new Rectangle(0, 0, bmpDest.Width, bmpDest.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData bitSrc = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { int stride = bitSrc.Stride; int stride2 = bitSrc.Stride * 2; unsafe { for (int y = 0; y < b.Height - 2; y++) { byte *ptrSrc = (byte *)bitSrc.Scan0 + y * bitSrc.Stride; byte *ptrDest = (byte *)bitSrc.Scan0 + y * bitData.Stride; for (int x = 0; x < b.Width - 2; x++) { // Set R channel (remember, bytes are BGR, not RGB, thanks to little endian byte order). int nPixelR = (((ptrSrc[x * 3 + 2] * m.TopLeft) + (ptrSrc[x * 3 + 5] * m.TopMid) + (ptrSrc[x * 3 + 8] * m.TopRight) + (ptrSrc[x * 3 + 2 + stride] * m.MidLeft) + (ptrSrc[x * 3 + 5 + stride] * m.Pixel) + (ptrSrc[x * 3 + 8 + stride] * m.MidRight) + (ptrSrc[x * 3 + 2 + stride2] * m.BottomLeft) + (ptrSrc[x * 3 + 5 + stride2] * m.BottomMid) + (ptrSrc[x * 3 + 8 + stride2] * m.BottomRight)) / m.Factor) + m.Offset; nPixelR = (int)System.Math.Max(0, System.Math.Min(255, nPixelR)); ptrDest[5 + stride] = (byte)nPixelR; // Set G channel. int nPixelG = (((ptrSrc[x * 3 + 1] * m.TopLeft) + (ptrSrc[x * 3 + 4] * m.TopMid) + (ptrSrc[x * 3 + 7] * m.TopRight) + (ptrSrc[x * 3 + 1 + stride] * m.MidLeft) + (ptrSrc[x * 3 + 4 + stride] * m.Pixel) + (ptrSrc[x * 3 + 7 + stride] * m.MidRight) + (ptrSrc[x * 3 + 1 + stride2] * m.BottomLeft) + (ptrSrc[x * 3 + 4 + stride2] * m.BottomMid) + (ptrSrc[x * 3 + 7 + stride2] * m.BottomRight)) / m.Factor) + m.Offset; nPixelG = (int)System.Math.Max(0, System.Math.Min(255, nPixelG)); ptrDest[4 + stride] = (byte)nPixelG; // Set B channel. int nPixelB = (((ptrSrc[x * 3 + 0] * m.TopLeft) + (ptrSrc[x * 3 + 3] * m.TopMid) + (ptrSrc[x * 3 + 6] * m.TopRight) + (ptrSrc[x * 3 + 0 + stride] * m.MidLeft) + (ptrSrc[x * 3 + 3 + stride] * m.Pixel) + (ptrSrc[x * 3 + 6 + stride] * m.MidRight) + (ptrSrc[x * 3 + 0 + stride2] * m.BottomLeft) + (ptrSrc[x * 3 + 3 + stride2] * m.BottomMid) + (ptrSrc[x * 3 + 6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset; nPixelB = (int)System.Math.Max(0, System.Math.Min(255, nPixelB)); ptrDest[3 + stride] = (byte)nPixelB; } } } } catch { if (bmpDest != null) { bmpDest.Dispose(); } throw; } finally { bmpDest.UnlockBits(bitData); b.UnlockBits(bitSrc); } return(bmpDest); }
public static Bitmap EdgeDetectQuick(Bitmap b) { ConvMatrix m = new ConvMatrix(); m.TopLeft = m.TopMid = m.TopRight = -1; m.MidLeft = m.Pixel = m.MidRight = 0; m.BottomLeft = m.BottomMid = m.BottomRight = 1; m.Offset = 127; return BitmapFilter.Conv3x3(b, m); }
public static Bitmap EdgeDetectConvolution(Bitmap b, EdgeDetectionMethod nType, byte nThreshold) { ConvMatrix m = new ConvMatrix(); // First we need to keep a copy of the original Bitmap. using (Bitmap bTemp = (Bitmap)b.Clone()) { try { switch (nType) { case EdgeDetectionMethod.Sobel: m.SetAll(0); m.TopLeft = m.BottomLeft = 1; m.TopRight = m.BottomRight = -1; m.MidLeft = 2; m.MidRight = -2; m.Offset = 0; break; case EdgeDetectionMethod.Prewitt: m.SetAll(0); m.TopLeft = m.MidLeft = m.BottomLeft = -1; m.TopRight = m.MidRight = m.BottomRight = 1; m.Offset = 0; break; case EdgeDetectionMethod.Kirsh: m.SetAll(-3); m.Pixel = 0; m.TopLeft = m.MidLeft = m.BottomLeft = 5; m.Offset = 0; break; } BitmapFilter.Conv3x3(b, m); switch (nType) { case EdgeDetectionMethod.Sobel: m.SetAll(0); m.TopLeft = m.TopRight = 1; m.BottomLeft = m.BottomRight = -1; m.TopMid = 2; m.BottomMid = -2; m.Offset = 0; break; case EdgeDetectionMethod.Prewitt: m.SetAll(0); m.BottomLeft = m.BottomMid = m.BottomRight = -1; m.TopLeft = m.TopMid = m.TopRight = 1; m.Offset = 0; break; case EdgeDetectionMethod.Kirsh: m.SetAll(-3); m.Pixel = 0; m.BottomLeft = m.BottomMid = m.BottomRight = 5; m.Offset = 0; break; } BitmapFilter.Conv3x3(bTemp, m); } catch { throw; } // GDI+ lies - return format is BGR, not RGB. BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData bmpData2 = bTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); try { int stride = bmpData.Stride; unsafe { byte* p = (byte*)(void*)bmpData.Scan0; byte* p2 = (byte*)(void*)bmpData2.Scan0; int nOffset = stride - b.Width * 3; int nWidth = b.Width * 3; int nPixel = 0; for (int y = 0; y < b.Height; ++y) { for (int x = 0; x < nWidth; ++x) { nPixel = (int)System.Math.Sqrt((p[0] * p[0]) + (p2[0] * p2[0])); if (nPixel < nThreshold) nPixel = nThreshold; if (nPixel > 255) nPixel = 255; p[0] = (byte)nPixel; ++p; ++p2; } p += nOffset; p2 += nOffset; } } } catch { throw; } finally { b.UnlockBits(bmpData); bTemp.UnlockBits(bmpData2); } } return b; }
public static Bitmap EmbossLaplacian(Bitmap b) { ConvMatrix m = new ConvMatrix(-1); m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 0; m.Pixel = 4; m.Offset = 127; return BitmapFilter.Conv3x3(b, m); }
public static Bitmap Sharpen(Bitmap b, int nWeight) { ConvMatrix m = new ConvMatrix(0); m.Pixel = nWeight; m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = -2; m.Factor = nWeight - 8; return BitmapFilter.Conv3x3(b, m); }
public static Bitmap MeanRemoval(Bitmap b, int nWeight) { ConvMatrix m = new ConvMatrix(-1); m.Pixel = nWeight; m.Factor = nWeight - 8; return BitmapFilter.Conv3x3(b, m); }
public static Bitmap Smooth(Bitmap b, int nWeight) { ConvMatrix m = new ConvMatrix(1); m.Pixel = nWeight; m.Factor = nWeight + 8; return BitmapFilter.Conv3x3(b, m); }
public static Bitmap Conv3x3(Bitmap b, ConvMatrix m) { // Avoid divide by zero errors. if (m.Factor == 0) throw new ArgumentException("Conversion matrix factor must be greater than zero.", "m"); Bitmap bmpDest = new Bitmap(b.Width, b.Height); // GDI+ lies - the return format is BGR, not RGB (stupid little-endian) BitmapData bitData = bmpDest.LockBits(new Rectangle(0, 0, bmpDest.Width, bmpDest.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData bitSrc = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); try { int stride = bitSrc.Stride; int stride2 = bitSrc.Stride * 2; unsafe { for (int y = 0; y < b.Height - 2; y++) { byte* ptrSrc = (byte*)bitSrc.Scan0 + y * bitSrc.Stride; byte* ptrDest = (byte*)bitSrc.Scan0 + y * bitData.Stride; for (int x = 0; x < b.Width - 2; x++) { // Set R channel (remember, bytes are BGR, not RGB, thanks to little endian byte order). int nPixelR = (((ptrSrc[x * 3 + 2] * m.TopLeft) + (ptrSrc[x * 3 + 5] * m.TopMid) + (ptrSrc[x * 3 + 8] * m.TopRight) + (ptrSrc[x * 3 + 2 + stride] * m.MidLeft) + (ptrSrc[x * 3 + 5 + stride] * m.Pixel) + (ptrSrc[x * 3 + 8 + stride] * m.MidRight) + (ptrSrc[x * 3 + 2 + stride2] * m.BottomLeft) + (ptrSrc[x * 3 + 5 + stride2] * m.BottomMid) + (ptrSrc[x * 3 + 8 + stride2] * m.BottomRight)) / m.Factor) + m.Offset; nPixelR = (int)System.Math.Max(0, System.Math.Min(255, nPixelR)); ptrDest[5 + stride] = (byte)nPixelR; // Set G channel. int nPixelG = (((ptrSrc[x * 3 + 1] * m.TopLeft) + (ptrSrc[x * 3 + 4] * m.TopMid) + (ptrSrc[x * 3 + 7] * m.TopRight) + (ptrSrc[x * 3 + 1 + stride] * m.MidLeft) + (ptrSrc[x * 3 + 4 + stride] * m.Pixel) + (ptrSrc[x * 3 + 7 + stride] * m.MidRight) + (ptrSrc[x * 3 + 1 + stride2] * m.BottomLeft) + (ptrSrc[x * 3 + 4 + stride2] * m.BottomMid) + (ptrSrc[x * 3 + 7 + stride2] * m.BottomRight)) / m.Factor) + m.Offset; nPixelG = (int)System.Math.Max(0, System.Math.Min(255, nPixelG)); ptrDest[4 + stride] = (byte)nPixelG; // Set B channel. int nPixelB = (((ptrSrc[x * 3 + 0] * m.TopLeft) + (ptrSrc[x * 3 + 3] * m.TopMid) + (ptrSrc[x * 3 + 6] * m.TopRight) + (ptrSrc[x * 3 + 0 + stride] * m.MidLeft) + (ptrSrc[x * 3 + 3 + stride] * m.Pixel) + (ptrSrc[x * 3 + 6 + stride] * m.MidRight) + (ptrSrc[x * 3 + 0 + stride2] * m.BottomLeft) + (ptrSrc[x * 3 + 3 + stride2] * m.BottomMid) + (ptrSrc[x * 3 + 6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset; nPixelB = (int)System.Math.Max(0, System.Math.Min(255, nPixelB)); ptrDest[3 + stride] = (byte)nPixelB; } } } } catch { if (bmpDest != null) bmpDest.Dispose(); throw; } finally { bmpDest.UnlockBits(bitData); b.UnlockBits(bitSrc); } return bmpDest; }