/// <summary> /// /// </summary> /// <param name="b"></param> /// <param name="nType"></param> /// <param name="nThreshold"></param> /// <returns></returns> public static bool EdgeDetectConvolution(Bitmap b, short nType, byte nThreshold) { ConvMatrix m = new ConvMatrix(); // I need to make a copy of this bitmap BEFORE I alter it 80) Bitmap bTemp = (Bitmap)b.Clone(); switch (nType) { case EDGE_DETECT_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 EDGE_DETECT_PREWITT: m.SetAll(0); m.TopLeft = m.MidLeft = m.BottomLeft = -1; m.TopRight = m.MidRight = m.BottomRight = 1; m.Offset = 0; break; case EDGE_DETECT_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 EDGE_DETECT_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 EDGE_DETECT_PREWITT: m.SetAll(0); m.BottomLeft = m.BottomMid = m.BottomRight = -1; m.TopLeft = m.TopMid = m.TopRight = 1; m.Offset = 0; break; case EDGE_DETECT_KIRSH: m.SetAll(-3); m.Pixel = 0; m.BottomLeft = m.BottomMid = m.BottomRight = 5; m.Offset = 0; break; } BitmapFilter.Conv3x3(bTemp, m); // GDI+ still lies to us - the return format is BGR, NOT RGB. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData bmData2 = bTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int stride = bmData.Stride; System.IntPtr Scan0 = bmData.Scan0; System.IntPtr Scan02 = bmData2.Scan0; unsafe { byte* p = (byte*)(void*)Scan0; byte* p2 = (byte*)(void*)Scan02; 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)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; } } b.UnlockBits(bmData); bTemp.UnlockBits(bmData2); return true; }
/// <summary> /// /// </summary> /// <param name="b"></param> /// <returns></returns> public static bool EmbossLaplacian(Bitmap b) { ConvMatrix m = new ConvMatrix(); m.SetAll(-1); m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 0; m.Pixel = 4; m.Offset = 127; return BitmapFilter.Conv3x3(b, m); }
/// <summary> /// /// </summary> /// <param name="b"></param> /// <returns></returns> public static bool 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); }
/// <summary> /// /// </summary> /// <param name="b"></param> /// <param name="nWeight"></param> /// <returns></returns> public static bool Sharpen(Bitmap b, int nWeight /* default to 11*/ ) { ConvMatrix m = new ConvMatrix(); m.SetAll(0); m.Pixel = nWeight; m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = -2; m.Factor = nWeight - 8; return BitmapFilter.Conv3x3(b, m); }
/// <summary> /// /// </summary> /// <param name="b"></param> /// <param name="nWeight"></param> /// <returns></returns> public static bool MeanRemoval(Bitmap b, int nWeight /* default to 9*/ ) { ConvMatrix m = new ConvMatrix(); m.SetAll(-1); m.Pixel = nWeight; m.Factor = nWeight - 8; return BitmapFilter.Conv3x3(b, m); }
/// <summary> /// /// </summary> /// <param name="b"></param> /// <param name="nWeight"></param> /// <returns></returns> public static bool GaussianBlur(Bitmap b, int nWeight /* default to 4*/) { ConvMatrix m = new ConvMatrix(); m.SetAll(1); m.Pixel = nWeight; m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 2; m.Factor = nWeight + 12; return BitmapFilter.Conv3x3(b, m); }
/// <summary> /// /// </summary> /// <param name="b"></param> /// <param name="nWeight"></param> /// <returns></returns> public static bool Smooth(Bitmap b, int nWeight /* default to 1 */) { ConvMatrix m = new ConvMatrix(); m.SetAll(1); m.Pixel = nWeight; m.Factor = nWeight + 8; return BitmapFilter.Conv3x3(b, m); }
/// <summary> /// /// </summary> /// <param name="b"></param> /// <param name="m"></param> /// <returns></returns> public static bool Conv3x3(Bitmap b, ConvMatrix m) { // Avoid divide by zero errors if (0 == m.Factor) return false; Bitmap bSrc = (Bitmap)b.Clone(); // GDI+ still lies to us - the return format is BGR, NOT RGB. BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); int stride = bmData.Stride; int stride2 = stride * 2; System.IntPtr Scan0 = bmData.Scan0; System.IntPtr SrcScan0 = bmSrc.Scan0; unsafe { byte* p = (byte*)(void*)Scan0; byte* pSrc = (byte*)(void*)SrcScan0; int nOffset = stride - b.Width * 3; int nWidth = b.Width - 2; int nHeight = b.Height - 2; int nPixel; for (int y = 0; y < nHeight; ++y) { for (int x = 0; x < nWidth; ++x) { nPixel = ((((pSrc[2] * m.TopLeft) + (pSrc[5] * m.TopMid) + (pSrc[8] * m.TopRight) + (pSrc[2 + stride] * m.MidLeft) + (pSrc[5 + stride] * m.Pixel) + (pSrc[8 + stride] * m.MidRight) + (pSrc[2 + stride2] * m.BottomLeft) + (pSrc[5 + stride2] * m.BottomMid) + (pSrc[8 + stride2] * m.BottomRight)) / m.Factor) + m.Offset); if (nPixel < 0) nPixel = 0; if (nPixel > 255) nPixel = 255; p[5 + stride] = (byte)nPixel; nPixel = ((((pSrc[1] * m.TopLeft) + (pSrc[4] * m.TopMid) + (pSrc[7] * m.TopRight) + (pSrc[1 + stride] * m.MidLeft) + (pSrc[4 + stride] * m.Pixel) + (pSrc[7 + stride] * m.MidRight) + (pSrc[1 + stride2] * m.BottomLeft) + (pSrc[4 + stride2] * m.BottomMid) + (pSrc[7 + stride2] * m.BottomRight)) / m.Factor) + m.Offset); if (nPixel < 0) nPixel = 0; if (nPixel > 255) nPixel = 255; p[4 + stride] = (byte)nPixel; nPixel = ((((pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) + (pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) + (pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid) + (pSrc[6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset); if (nPixel < 0) nPixel = 0; if (nPixel > 255) nPixel = 255; p[3 + stride] = (byte)nPixel; p += 3; pSrc += 3; } p += nOffset; pSrc += nOffset; } } b.UnlockBits(bmData); bSrc.UnlockBits(bmSrc); return true; }