예제 #1
0
        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));
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
 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);
 }
예제 #5
0
        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;
        }
예제 #6
0
 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);
 }
예제 #7
0
 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);
 }
예제 #8
0
 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);
 }
예제 #9
0
 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);
 }
예제 #10
0
        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;
        }