Click here to Skip to main content
15,886,199 members
Articles / Artificial Intelligence / Neural Networks

Multiple convolution neural networks approach for online handwriting recognition

Rate me:
Please Sign up or sign in to vote.
4.95/5 (37 votes)
9 Apr 2013CPOL8 min read 76K   25.1K   74  
The research focuses on the presentation of word recognition technique for an online handwriting recognition system which uses multiple component neural networks (MCNN) as the exchangeable parts of the classifier.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.Threading.Tasks;
namespace UPImage
{
    public class ImageProcessing
    {
        public static byte[] ConvertGrayscaleBitmaptoBytes(Bitmap original)
        {
            Bitmap gsBitmap = (Bitmap)original.Clone();
            if (original.PixelFormat != PixelFormat.Format8bppIndexed)
            {
                gsBitmap = ColorToIndexedGrayscale(original);
            }

            byte[] grayscalebytes = new byte[gsBitmap.Width * gsBitmap.Height];
            BitmapData bmpData = gsBitmap.LockBits(new Rectangle(0, 0, gsBitmap.Width, gsBitmap.Height),
                                                ImageLockMode.ReadOnly,
                                                gsBitmap.PixelFormat);
            int bytes = Math.Abs(bmpData.Stride) * gsBitmap.Height;
            byte[] rgbValues = new byte[bytes];

            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, rgbValues, 0, bytes);
            gsBitmap.UnlockBits(bmpData);
            //
            for (int h = 0; h < gsBitmap.Height; h++)
            {
                for (int w = 0; w < gsBitmap.Width; w++)
                {
                    grayscalebytes[h * gsBitmap.Width + w] = rgbValues[h * bmpData.Stride + w];
                }
            }

            return grayscalebytes;

        }
        public static Bitmap ColorToGrayscale(Bitmap original)
        {
            //create a blank bitmap the same size as original
            Bitmap newBitmap = new Bitmap(original.Width, original.Height);

            //get a graphics object from the new image
            Graphics g = Graphics.FromImage(newBitmap);

            //create the grayscale ColorMatrix
            ColorMatrix colorMatrix = new ColorMatrix(
               new float[][] 
              {
                 new float[] {.3f, .3f, .3f, 0, 0},
                 new float[] {.59f, .59f, .59f, 0, 0},
                 new float[] {.11f, .11f, .11f, 0, 0},
                 new float[] {0, 0, 0, 1, 0},
                 new float[] {0, 0, 0, 0, 1}
              });

            //create some image attributes
            ImageAttributes attributes = new ImageAttributes();

            //set the color matrix attribute
            attributes.SetColorMatrix(colorMatrix);

            //draw the original image on the new image
            //using the grayscale color matrix
            g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
               0, 0, original.Width, original.Height, GraphicsUnit.Pixel, attributes);

            //dispose the Graphics object
            g.Dispose();
            return newBitmap;
        }
        public static Bitmap ColorToIndexedGrayscale(Bitmap original)
        {
            int w = original.Width,
                h = original.Height,
                r, ic, oc, bmpStride, outputStride, bytesPerPixel;
            PixelFormat pfIn = original.PixelFormat;
            ColorPalette palette;
            Bitmap output;
            BitmapData bmpData, outputData;

            //Create the new bitmap
            output = new Bitmap(w, h, PixelFormat.Format8bppIndexed);

            //Build a grayscale color Palette
            palette = output.Palette;
            for (int i = 0; i < 256; i++)
            {
                Color tmp = Color.FromArgb(255, i, i, i);
                palette.Entries[i] = Color.FromArgb(255, i, i, i);
            }
            output.Palette = palette;

            //No need to convert formats if already in 8 bit
            if (pfIn == PixelFormat.Format8bppIndexed)
            {
                output = (Bitmap)original.Clone();

                //Make sure the palette is a grayscale palette and not some other
                //8-bit indexed palette
                output.Palette = palette;

                return output;
            }

            //Get the number of bytes per pixel
            switch (pfIn)
            {
                case PixelFormat.Format24bppRgb: bytesPerPixel = 3; break;
                case PixelFormat.Format32bppArgb: bytesPerPixel = 4; break;
                case PixelFormat.Format32bppRgb: bytesPerPixel = 4; break;
                default: throw new InvalidOperationException("Image format not supported");
            }

            //Lock the images
            bmpData = original.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly,
                                   pfIn);
            outputData = output.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.WriteOnly,
                                         PixelFormat.Format8bppIndexed);
            bmpStride = bmpData.Stride;
            outputStride = outputData.Stride;

            int bmpBytes = Math.Abs(bmpData.Stride) * original.Height;
            byte[] rgbValues = new byte[bmpBytes];
            int indexdedBytes = Math.Abs(outputStride) * h;
            byte[] indexedValues = new byte[indexdedBytes];
            //Traverse each pixel of the image
           
            System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, rgbValues, 0, bmpBytes);

            if (bytesPerPixel == 3)
            {
                //Convert the pixel to it's luminance using the formula:
                // L = .299*R + .587*G + .114*B
                //Note that ic is the input column and oc is the output column
                for (r = 0; r < h; r++)
                    for (ic = oc = 0; oc < w; ic += 3, ++oc)
                        indexedValues[r * outputStride + oc] = (byte)(int)
                            (0.299f * rgbValues[r * bmpStride + ic] +
                                0.587f * rgbValues[r * bmpStride + ic + 1] +
                                0.114f * rgbValues[r * bmpStride + ic + 2]);
            }
            else //bytesPerPixel == 4
            {
                //Convert the pixel to it's luminance using the formula:
                // L = alpha * (.299*R + .587*G + .114*B)
                //Note that ic is the input column and oc is the output column
                for (r = 0; r < h; r++)
                    for (ic = oc = 0; oc < w; ic += 4, ++oc)
                        indexedValues[r * outputStride + oc] = (byte)(int)
                            ((rgbValues[r * bmpStride + ic] / 255.0f) *
                            (0.299f * rgbValues[r * bmpStride + ic + 1] +
                                0.587f * rgbValues[r * bmpStride + ic + 2] +
                                0.114f * rgbValues[r * bmpStride + ic + 3]));
            }
            
            //Copy the data from the byte array into BitmapData.Scan0
            System.Runtime.InteropServices.Marshal.Copy(indexedValues, 0, outputData.Scan0, indexedValues.Length);
            //Unlock the images
            original.UnlockBits(bmpData);
            output.UnlockBits(outputData);

            return output;
        }
        public static Bitmap ResizeBitmap(Bitmap original, int newWidth, int newHeight)
        {
            //a holder for the result
            Bitmap result = new Bitmap(newWidth, newHeight);

            //use a graphics object to draw the resized image into the bitmap
            using (Graphics graphics = Graphics.FromImage(result))
            {
                //set the resize quality modes to high quality
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //draw the image into the target bitmap
                graphics.DrawImage(original, 0, 0, result.Width, result.Height);
            }

            //return the resulting bitmap
            return result;
        }
        public static bool IsGrayscale(Bitmap original)
        {
            bool ret = false;

            // check pixel format
            if (original.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                ret = true;
                // check palette
                ColorPalette cp = original.Palette;
                Color c;
                // init palette
                for (int i = 0; i < 256; i++)
                {
                    c = cp.Entries[i];
                    if ((c.R != i) || (c.G != i) || (c.B != i))
                    {
                        ret = false;
                        break;
                    }
                }
            }
            return ret;
        }
        public static Rectangle RectangeBoundarybyColor(Bitmap original, int colorIndex)
        {
            Rectangle rect = new Rectangle(0, 0, 0, 0);
            Bitmap bmTemp;
            if (IsGrayscale(original) == false)
            {
                //convert bitmap to indexed grayscale
                bmTemp = ColorToIndexedGrayscale(original);
            }
            else
            {
                bmTemp = original;
            }
            BitmapData originalData = bmTemp.LockBits(
             new Rectangle(0, 0, bmTemp.Width, bmTemp.Height),
             ImageLockMode.ReadOnly, bmTemp.PixelFormat);
            //do some thing
            // Get the address of the first line.
            IntPtr ptr = originalData.Scan0;
            // Declare an array to hold the bytes of the bitmap.
            int bytes = System.Math.Abs(originalData.Stride) * bmTemp.Height;
            byte[] rgbValues = new byte[bytes];
            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
            //get pattern rectange X;
            for (int h = 0; h < bmTemp.Height; h++)
            {
                for (int w = 0; w < bmTemp.Width; w++)
                {
                    if (rgbValues[h * originalData.Stride + w] != colorIndex)
                    {
                        rect.Y = h;
                        goto exitloop1;
                    }
                }
            }
        exitloop1:   //get pattern rectange Y;
            for (int w = 0; w < bmTemp.Width; w++)
            {
                for (int h = 0; h < bmTemp.Height; h++)
                {
                    if (rgbValues[h * originalData.Stride + w] != colorIndex)
                    {
                        rect.X = w;
                        goto exitloop2;
                    }
                }
            }
        exitloop2:    //get pattern rectange Height;
            for (int h = bmTemp.Height - 1; h > 0; h--)
            {
                for (int w = bmTemp.Width - 1; w > 0; w--)
                {
                    if (rgbValues[h * originalData.Stride + w] != colorIndex)
                    {
                        rect.Height = h - rect.Y;
                        goto exitloop3;
                    }
                }
            }
        exitloop3:   //get pattern rectange Width;
            for (int w = bmTemp.Width - 1; w > 0; w--)
            {
                for (int h = bmTemp.Height - 1; h > 0; h--)
                {
                    if (rgbValues[h * originalData.Stride + w] != colorIndex)
                    {
                        rect.Width = w - rect.X;
                        goto exitloop4;
                    }
                }
            }

        exitloop4:
            bmTemp.UnlockBits(originalData);
            bmTemp.Dispose();

            return rect;

        }
        public static Rectangle PatternRectangeBoundary(Bitmap original, int colorIndex, int hStep, int vStep, bool bTopStart)
        {
            //check steps if <= 0
            if (hStep <= 0)
            {
                hStep = 1;
            }
            if (vStep <= 0)
            {
                vStep = 1;
            }
            Rectangle rect = new Rectangle(0, 0, 0, 0);
            Bitmap gsBitmap=null;
            if (IsGrayscale(original) == false)
            {
                //convert bitmap to indexed grayscale
                gsBitmap = ColorToIndexedGrayscale(original);
            }
            else
            {
                gsBitmap = original;
            }

            if (gsBitmap != null)
            {
                BitmapData gsBitmapData = gsBitmap.LockBits(
                           new Rectangle(0, 0, gsBitmap.Width, gsBitmap.Height),
                           ImageLockMode.ReadOnly, gsBitmap.PixelFormat);
                // Get the address of the first line.
                IntPtr ptr = gsBitmapData.Scan0;
                // Declare an array to hold the bytes of the bitmap.
                int bytes = Math.Abs(gsBitmapData.Stride) * gsBitmap.Height;
                byte[] rgbValues = new byte[bytes];

                // Copy the RGB values into the array.
                System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
                gsBitmap.UnlockBits(gsBitmapData);
                bool bDetectedPattern = false;
                //initial boundary

                if (bTopStart)
                {
                    #region get rectange from pattern's top
                    //Initialize boundary of a pattern candidate
                    for (int h = 0; h < gsBitmap.Height; h++)
                    {
                        for (int w = 0; w < gsBitmap.Width; w++)
                        {
                            byte value=rgbValues[h * gsBitmapData.Stride + w];
                            if (value <= colorIndex - 2 || value >= colorIndex + 2)
                            {
                                rect.X = w;
                                rect.Y = h;
                                rect.Width = 1;
                                rect.Height = 1;
                                //pattern is detected
                                bDetectedPattern = true;
                                goto exitloop;
                            }
                        }

                    }
                exitloop:
                    if (bDetectedPattern)
                    {
                        bool _bBoundaryCompleted = false;
                        while (_bBoundaryCompleted == false)
                        {
                            _bBoundaryCompleted = true;
                            //expand boundary
                            //check all pixel of bottom = background color

                            for (int i = 1; i <= vStep; i++)
                            {
                                for (int w = rect.X; w < (rect.X + rect.Width); w += 1)
                                {
                                    int bottom = rect.Y + rect.Height + i;
                                    if (bottom < gsBitmap.Height)
                                    {
                                        byte value=rgbValues[bottom * gsBitmapData.Stride + w];
                                        if (value <= colorIndex - 2 || value >= colorIndex + 2)
                                        {
                                            rect.Height += i;
                                            _bBoundaryCompleted = false;
                                            w = rect.X;
                                            i = 1;
                                        }

                                    }
                                }
                            }

                            //check all pixel of left = background color

                            for (int i = 1; i <= hStep; i++)
                            {
                                for (int h = rect.Y; h < (rect.Y + rect.Height); h += 1)
                                {
                                    int left = rect.X - i;
                                    if (left >= 0)
                                    {
                                        byte value=rgbValues[h * gsBitmapData.Stride + left] ;
                                        if (value <= colorIndex - 2 || value >= colorIndex + 2)
                                        {
                                            rect.X -= i;
                                            rect.Width += i;
                                            _bBoundaryCompleted = false;
                                            h = rect.Y;
                                            i = 1;
                                        }

                                    }
                                }
                            }


                            //check all of right =background color

                            for (int i = 1; i <= hStep; i++)
                            {
                                for (int h = rect.Y; h < (rect.Y + rect.Height); h += 1)
                                {
                                    int right = rect.X + rect.Width + i;
                                    if (right < gsBitmap.Width)
                                    {
                                         byte value=rgbValues[h * gsBitmapData.Stride + right];
                                         if (value <= colorIndex - 2 || value >= colorIndex + 2)
                                        {
                                            rect.Width += i;
                                            _bBoundaryCompleted = false;
                                            h = rect.Y;
                                            i = 1;
                                        }
                                    }


                                }
                            }

                        }

                    }
                    #endregion
                }
                else
                {
                    #region get rectange from pattern's left
                    //Initialize boundary of a pattern candidate
                    for (int w = 0; w < gsBitmap.Width; w++)
                    {
                        for (int h = 0; h < gsBitmap.Height; h++)
                        {
                            byte value=rgbValues[h * gsBitmapData.Stride + w];
                            if (value <= colorIndex-2||value>=colorIndex+2)
                            {
                                rect.X = w;
                                rect.Y = h;
                                rect.Width = 1;
                                rect.Height = 1;
                                //pattern is detected
                                bDetectedPattern = true;
                                goto exitloop1;
                            }
                        }

                    }
                exitloop1:
                    if (bDetectedPattern)
                    {
                        bool _bBoundaryCompleted = false;
                        while (_bBoundaryCompleted == false)
                        {
                            _bBoundaryCompleted = true;
                            //expand boundary


                            //check all of right =background color

                            for (int i = 1; i <= hStep; i++)
                            {
                                for (int h = rect.Y; h < (rect.Y + rect.Height); h += 1)
                                {
                                    int right = rect.X + rect.Width + i;
                                    if (right < gsBitmap.Width)
                                    {
                                         byte value=rgbValues[h * gsBitmapData.Stride + right];
                                         if (value <= colorIndex - 2 || value >= colorIndex + 2)
                                        {
                                            rect.Width += i;
                                            _bBoundaryCompleted = false;
                                            h = rect.Y;
                                            i = 1;
                                        }
                                    }


                                }
                            }

                            //check all pixel of bottom = background color

                            for (int i = 1; i <= vStep; i++)
                            {
                                for (int w = rect.X; w < (rect.X + rect.Width); w += 1)
                                {
                                    int bottom = rect.Y + rect.Height + i;
                                    if (bottom < gsBitmap.Height)
                                    {
                                        byte value=rgbValues[bottom * gsBitmapData.Stride + w];
                                        if (value <= colorIndex - 2 || value >= colorIndex + 2)
                                        {
                                            rect.Height += i;
                                            _bBoundaryCompleted = false;
                                            w = rect.X;
                                            i = 1;
                                        }

                                    }
                                }
                            }

                            //check all pixel of top = background color

                            for (int i = 1; i <= vStep; i++)
                            {
                                for (int w = rect.X; w < (rect.X + rect.Width); w += 1)
                                {
                                    int top = rect.Y - i;
                                    if (top >= 0)
                                    {
                                        byte value=rgbValues[top * gsBitmapData.Stride + w];
                                        if (value <= colorIndex - 2 || value >= colorIndex + 2)
                                        {
                                            rect.Y -= i;
                                            rect.Height += i;
                                            _bBoundaryCompleted = false;
                                            w = rect.X;
                                            i = 1;
                                        }

                                    }
                                }
                            }

                        }

                    }
                    #endregion
                }
          
            }
            return rect;

        }
        public static Bitmap ByteDataToBitmap(byte[] data, Size size)
        {
            //Here create the Bitmap to the know height, width and format

            Bitmap bmp = new Bitmap(size.Width, size.Height, PixelFormat.Format8bppIndexed);
            ColorPalette ncp = bmp.Palette;
            for (int i = 0; i < 256; i++)
                ncp.Entries[i] = Color.FromArgb(255, i, i, i);
            bmp.Palette = ncp;

            //Create a BitmapData and Lock all pixels to be written 
            BitmapData bmpData = bmp.LockBits(
                                    new Rectangle(0, 0, bmp.Width, bmp.Height),
                                    ImageLockMode.WriteOnly, bmp.PixelFormat);
            int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
            byte[] rgbValues = new byte[bytes];
            for (int i = 0; i < bytes; i++)
            {
                rgbValues[i] = 255;
            }
            int bmpWidth = bmp.Width;
            int bmpHeight = bmp.Height;
            //
            /*TODO: Check potentially-changing upper bound expression "gsBitmap.Height" which is now called only *once*,
            to ensure the new Parallel.For call matches behavior in the original for-loop
            (where this upper bound expression had previously been evaluated at the start of *every* loop iteration).*/
            Parallel.For(0, bmpHeight, (h, loopstate) =>
            {
                for (int w = 0; w < bmpWidth; w++)
                {
                    rgbValues[h * bmpData.Stride + w] = data[h * bmpWidth + w];
                }

            });
            //Copy the data from the byte array into BitmapData.Scan0
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, bmpData.Scan0, rgbValues.Length);
            //Unlock the pixels
            bmp.UnlockBits(bmpData);

            //Return the bitmap 

            return bmp;
        }
        public static Bitmap MarkIndexedPattern(Bitmap original, int pendWidth,byte colorBackground)
        {
            if (original != null)
            {
                Bitmap gsBitmap = (Bitmap)original.Clone();
                if (original.PixelFormat != PixelFormat.Format8bppIndexed)
                {
                    gsBitmap = ImageProcessing.ColorToIndexedGrayscale(original);
                }

                byte[] grayscalebytes = new byte[gsBitmap.Width * gsBitmap.Height];
                BitmapData bmpData = gsBitmap.LockBits(new Rectangle(0, 0, gsBitmap.Width, gsBitmap.Height),
                                                    ImageLockMode.ReadOnly,
                                                    gsBitmap.PixelFormat);
                int bytes = Math.Abs(bmpData.Stride) * gsBitmap.Height;
                byte[] rgbValues = new byte[bytes];

                System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, rgbValues, 0, bytes);
                gsBitmap.UnlockBits(bmpData);
                //
                int[] marks = new int[gsBitmap.Width];
                // fill marks values
                for (int i = 0; i < gsBitmap.Width; i++)
                {
                    marks[i] = 0;
                }

                for (int w = 0; w < gsBitmap.Width; w++)
                {
                    int cuts = 0; //number of cuts per column
                    for (int h = 0; h < gsBitmap.Height; h++)
                    {
                        grayscalebytes[w + gsBitmap.Width * h] = rgbValues[h * bmpData.Stride + w];
                        if (grayscalebytes[w + gsBitmap.Width * h] != colorBackground)
                        {
                            cuts++; //
                        }
                    }
                    //check if cuts >penWidth
                    if (cuts > 2* pendWidth)
                    {
                        marks[w] = 1;
                    }
                }
                // average marks
                bool bStart = false;
                int iStart = 0;
                int iStop = 0;
                int iEvarage = 0;
                if (marks.First() == 0)
                {
                    bStart = true;
                }
                for (int i = 1; i < marks.Count(); i++)
                {
                    if (marks[i] != marks[i - 1])
                    {
                        bStart = !bStart;
                        if (bStart == false)
                        {
                            iStop = i;
                            iEvarage = iStart + (int)Math.Ceiling((iStop - iStart) / 2.0);
                            if(iEvarage>=2*pendWidth)
                            for (int h = 0; h < gsBitmap.Height; h++)
                            {
                              
                                grayscalebytes[iEvarage + gsBitmap.Width * h] =0;

                            }
                        }
                        else
                        {
                            iStart = i;
                            iStop = i;
                        }
                    }
                }
                gsBitmap = ByteDataToBitmap(grayscalebytes, new Size(gsBitmap.Width, gsBitmap.Height));
                return gsBitmap;
            }
            else
            {
                return null;
            }

        }
        public static Bitmap CreateNoneIndexedImage(Bitmap original)
        {
            Bitmap newBmp = new Bitmap(original.Width, original.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            using (var gfx = Graphics.FromImage(newBmp))
            {
                gfx.DrawImage(original, 0, 0);
            }
            return newBmp;
        }
        public static Bitmap FillColor(Bitmap original, Rectangle rect, int colorIndex)
        {
            Bitmap bmpTemp;
            if (ImageProcessing.IsGrayscale(original))
            {
                bmpTemp = original;
            }
            else
            {
                 //change to indexed grayscale bitmap
                bmpTemp = ImageProcessing.ColorToIndexedGrayscale(original);
            }
            BitmapData bmpData = bmpTemp.LockBits(
            new Rectangle(0, 0, bmpTemp.Width, bmpTemp.Height),
            ImageLockMode.ReadWrite, bmpTemp.PixelFormat);
            //do some thing
            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap.
            int bytes = System.Math.Abs(bmpData.Stride) * bmpTemp.Height;
            byte[] rgbValues = new byte[bytes];
            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
            //check rectange
            if (rect.X + rect.Width >= bmpTemp.Width)
            {
                rect.Width = bmpTemp.Width - rect.X - 1;
            }
            if (rect.Y + rect.Height >= bmpTemp.Height)
            {
                rect.Height = bmpTemp.Height - rect.Y - 1;
            }
            //
            for (int w = rect.X; w <= rect.Width + rect.X; w++)
            {
                for (int h = rect.Y; h <= rect.Height + rect.Y; h++)
                {
                    if (rgbValues[h * bmpData.Stride + w] != colorIndex)
                    {
                        rgbValues[h * bmpData.Stride + w] = Convert.ToByte(colorIndex);
                    }
                }

            }
            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
            // Unlock the bits.
            bmpTemp.UnlockBits(bmpData);
            return bmpTemp;

        }
        public static Bitmap CreateColorPad(Bitmap original, Color color, int padWidth, int padHeight)
        {
            Bitmap bmpTemp = CreateNoneIndexedImage(original);
            int width = bmpTemp.Width + padWidth;
            int height = bmpTemp.Height + padHeight;
            Bitmap bmpNew = new Bitmap(width, height, bmpTemp.PixelFormat);
            Graphics graph = Graphics.FromImage(bmpNew);
            Brush brush = new SolidBrush(color);
            graph.FillRectangle(brush, new Rectangle(0, 0, width, height));
            graph.DrawImage(bmpTemp,(int) Math.Floor((double)padWidth/2.0),(int) Math.Floor((double)padHeight/2.0));
            graph.Dispose();
            return bmpNew;

        }
        public static List<InputPattern> GetChildrenPatterns(InputPattern parentPattern, int hStep, int vStep, bool isTopStart, int minWidth, int minHeight)
        {
            List<InputPattern> patternlist = null;
            parentPattern.GetPatternBoundaries(hStep, vStep, isTopStart, minWidth, minHeight);
            if (parentPattern.PatternRects.Count > 0)
            {
                patternlist = new List<InputPattern>();
                foreach (var rect in parentPattern.PatternRects)
                {
                    Bitmap bmp = new Bitmap(rect.Width, rect.Height);
                    Graphics graph = Graphics.FromImage(bmp);
                    graph.DrawImage(parentPattern.OriginalBmp, 0, 0, rect, GraphicsUnit.Pixel);
                    int x = parentPattern.OriginalRectangle.X + rect.X;
                    int y = parentPattern.OriginalRectangle.Y + rect.Y;
                    Rectangle newRect = new Rectangle(x, y, rect.Width, rect.Height);
                    InputPattern childPattern = new InputPattern(bmp, 255, newRect);
                    patternlist.Add(childPattern);
                    graph.Dispose();
                }

            }

            return patternlist;
        }
        public static Bitmap Contuor(Bitmap original)
        {
            Bitmap bmp = null;
            if (IsGrayscale(original) == false)
            {
                //convert bitmap to indexed grayscale
                bmp = ColorToIndexedGrayscale(original);
            }
            else
            {
                bmp = (Bitmap) original.Clone();
            }
            BitmapData originalData = bmp.LockBits(
            new Rectangle(0, 0, bmp.Width, bmp.Height),
            ImageLockMode.ReadWrite, bmp.PixelFormat);
            //do some thing
            // Get the address of the first line.
            IntPtr ptr = originalData.Scan0;
            // Declare an array to hold the bytes of the bitmap.
            int bytes = System.Math.Abs(originalData.Stride) * bmp.Height;
            byte[] rgbValues = new byte[bytes];
            byte[] rgbValues1 = new byte[bytes];
            // Copy the RGB values into the array.
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues1, 0, bytes);

            for (int h = 1; h < bmp.Height-1; h++)
            {
                for (int w = 1; w < bmp.Width-1; w++)
                {
                    if (rgbValues[(h - 1) * originalData.Stride + (w - 1)] != 255 && rgbValues[(h - 1) * originalData.Stride + (w)] != 255 &&
                        rgbValues[(h - 1) * originalData.Stride + (w + 1)] != 255 && rgbValues[h * originalData.Stride + (w - 1)] != 255 &&
                        rgbValues[h * originalData.Stride + w] != 255 && rgbValues[h * originalData.Stride + (w + 1)] != 255 && 
                        rgbValues[(h + 1) * originalData.Stride + (w - 1)] != 255 && rgbValues[(h + 1) * originalData.Stride + w] != 255 && 
                        rgbValues[(h + 1) * originalData.Stride + (w + 1)] != 255)
                    {
                        rgbValues1[h * originalData.Stride + w] =(byte) 255;
                    }
                }
            }
            //check if w=0;
            for (int h = 1; h < bmp.Height-1 ; h++)
            {
                if (rgbValues[(h - 1) * originalData.Stride ] != 255 && rgbValues[(h - 1) * originalData.Stride+ 1] != 255 &&
                      rgbValues[h * originalData.Stride ] != 255 && rgbValues[h * originalData.Stride + 1] != 255 &&
                      rgbValues[(h + 1) * originalData.Stride ] != 255 && rgbValues[(h + 1) * originalData.Stride +1] != 255)
                {
                    rgbValues1[h * originalData.Stride] = (byte)255;
                }
            }
            //check if w=0;
            for (int w = 1; w < bmp.Width-1; w++)
            {
                if (rgbValues[w-1] != 255 && rgbValues[w] != 255 &&
                      rgbValues[w+1] != 255 && rgbValues[originalData.Stride + (w-1)] != 255 &&
                      rgbValues[originalData.Stride+w] != 255 && rgbValues[originalData.Stride + (w+1)] != 255)
                {
                    rgbValues1[w] = (byte)255;
                }
            }
            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues1, 0, ptr, bytes);
            bmp.UnlockBits(originalData);
            return bmp;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Vietnam Maritime University
Vietnam Vietnam
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions