• 图像处理工具箱


    还只是个菜鸟,不过想开个博客,记录一下自己的学习过程!

    最近在一家医疗软件公司实习,负责的是OCR(光学字符识别)部分!进行OCR之前难免会碰到图像处理,因此写了一个图像处理工具箱(ImageProcessUtilities),看网上有人讲过在进行OCR之前,进行图像二值化,图像锐化,中值滤波,线性灰度变化,转换为黑白灰度图完全就足够了!

    这个工具箱大概也是实现这些功能,首先类视图,

    下面给出代码,希望大家多批评指下,之后会后续发布OCR检索其他方面的工具,诸如文字后处理的正则表达等!

     public class ImageProcessUtility
        {
    
            //暂时只对24位图和8位图进行处理
    
            #region 图像扩边函数
            /// <summary>
            /// 图像扩边函数
            /// </summary>
            /// <param name="width">扩边后图像的宽度</param>
            /// <param name="height">扩边后图像的高度</param>
            /// <param name="inputBitmap">需要扩边的图像</param>
            /// <returns>完成扩边后的图像</returns>
            public static Bitmap ImageExpand(int width, int height, Bitmap inputBitmap)
            {
                try
                {
                    Bitmap bitmap = new Bitmap(width, height);
                    Graphics g = Graphics.FromImage(bitmap);
                    g.Clear(Color.Black);
                    int start_X = (width - inputBitmap.Width) / 2;
                    int start_Y = (height - inputBitmap.Height) / 2;
    
                    g.DrawImage(inputBitmap, new Point(start_X, start_Y));
                    g.Dispose();
                    return bitmap;
                }
                catch
                {
                    return null;
                }
            }
            #endregion
    
            #region 图像缩放函数
            /// <summary>
            /// 图像缩放函数
            /// </summary>
            /// <param name="scale">缩放因子</param>
            /// <param name="inputBitmap">需要缩放的图像</param>
            /// <returns>缩放后的图像</returns>
            public static Bitmap ImageResize(double scale, Bitmap inputBitmap)
            {
                try
                {
                    int newWidth = Convert.ToInt32(inputBitmap.Width * scale);
                    int newHeight = Convert.ToInt32(inputBitmap.Height * scale);
                    Bitmap bitmap = new Bitmap(newWidth, newHeight);
    
                    Graphics g = Graphics.FromImage(bitmap);
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
    
                    g.DrawImage(inputBitmap, new Rectangle(0, 0, newWidth, newHeight),
                        new Rectangle(0,0,inputBitmap.Width, inputBitmap.Height), GraphicsUnit.Pixel);                
    
                    g.Dispose();
                    return bitmap;
                }
                catch 
                {
                    return null;
                }
    
            }
            #endregion
    
            #region 转换为8位灰度图像
            /// <summary>
            /// 将图像转换成8位Bitmap图像函数
            /// </summary>
            /// <param name="inputBitmap">要转换的图像</param>
            /// <returns>转换后的图像</returns>
            public static Bitmap ToGray(Bitmap inputBitmap)
            {
                Bitmap bmp = new Bitmap(inputBitmap.Width, inputBitmap.Height, PixelFormat.Format8bppIndexed);
    
                //设定实例BitmapData相关信息  
                Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    
                BitmapData data = inputBitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
                //锁定bmp到系统内存中  
                BitmapData data2 = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
    
                //获取位图中第一个像素数据的地址  
                IntPtr ptr = data.Scan0;
                IntPtr ptr2 = data2.Scan0;
    
                int numBytes = data.Stride * data.Height;
                int numBytes2 = data2.Stride * data2.Height;
    
                int n2 = data2.Stride - bmp.Width; //// 显示宽度与扫描线宽度的间隙  
    
                byte[] rgbValues = new byte[numBytes];
                byte[] rgbValues2 = new byte[numBytes2];
                //将bmp数据Copy到申明的数组中  
                Marshal.Copy(ptr, rgbValues, 0, numBytes);
                Marshal.Copy(ptr2, rgbValues2, 0, numBytes2);
    
                int n = 0;
    
                for (int y = 0; y < bmp.Height; y++)
                {
                    for (int x = 0; x < bmp.Width * 3; x += 3)
                    {
                        int i = data.Stride * y + x;
    
                        double value = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114; //计算灰度  
    
                        rgbValues2[n] = (byte)value;
    
                        n++;
                    }
                    n += n2; //跳过差值  
                }
    
                //将数据Copy到内存指针  
                Marshal.Copy(rgbValues, 0, ptr, numBytes);
                Marshal.Copy(rgbValues2, 0, ptr2, numBytes2);
    
                //// 下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度  
                ColorPalette tempPalette;
                using (Bitmap tempBmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
                {
                    tempPalette = tempBmp.Palette;
                }
                for (int i = 0; i < 256; i++)
                {
                    tempPalette.Entries[i] = Color.FromArgb(i, i, i);
                }
    
                bmp.Palette = tempPalette;
    
    
                //从系统内存解锁bmp  
                inputBitmap.UnlockBits(data);
                bmp.UnlockBits(data2);
    
                return bmp;
            }
            #endregion
    
            #region 转换为二值图像
            /// <summary>
            /// 图像二值化函数
            /// </summary>
            /// <param name="grayValue">需要二值化的图像</param>
            /// <param name="inputBitmap">阈值</param>
            /// <returns>完成二值化后的图像</returns>
            public static Bitmap ToBinary(int grayValue, Bitmap inputBitmap)
            {
                //获取图像长宽
                int w = inputBitmap.Width;
                int h = inputBitmap.Height;
                //锁定位图信息
                Bitmap dstBitmap = new Bitmap(inputBitmap.Width, inputBitmap.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                System.Drawing.Imaging.BitmapData srcData = inputBitmap.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                System.Drawing.Imaging.BitmapData dstData = dstBitmap.LockBits(new Rectangle(0, 0, w, h), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                unsafe
                {
    
                    byte* pIn = (byte*)srcData.Scan0.ToPointer();
                    byte* pOut = (byte*)dstData.Scan0.ToPointer();
                    byte* p;
                    int stride = srcData.Stride;
                    int r, g, b;
                    //二值化过程
                    for (int y = 0; y < h; y++)
                    {
                        for (int x = 0; x < w; x++)
                        {
                            p = pIn;
                            r = p[2];
                            g = p[1];
                            b = p[0];
                            //灰度值等于V的为黑色,反之为白色
                            pOut[0] = pOut[1] = pOut[2] = (byte)(((byte)(r << 16 | g << 8 | b) == grayValue)
                            ? 255 : 0);
                            pIn += 3;
                            pOut += 3;
                        }
                        pIn += srcData.Stride - w * 3;
                        pOut += srcData.Stride - w * 3;
                    }
                    //解除锁定
                    inputBitmap.UnlockBits(srcData);
                    dstBitmap.UnlockBits(dstData);
                    //返回处理后的图像
                    return dstBitmap;
                }
            }
            #endregion
    
            #region 中值滤波
            /// <summary>
            /// 图像中值滤波,在进行滤波前,
            /// 若是RGB图,需要将其转换为灰度图
            /// </summary>
            /// <param name="mode">窗口模式:
            /// 0:3*3窗口
            /// 1:5*5窗口
            /// </param>
            /// <param name="inputBitmap"></param>
            /// <returns></returns>
            public static Bitmap ImageMedianFilter(int mode, Bitmap inputBitmap)
            {
                try
                {
                    if (inputBitmap.PixelFormat == PixelFormat.Format24bppRgb)
                        inputBitmap = ToGray(inputBitmap);
                    Rectangle rect = new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height);
                    BitmapData bmpData = inputBitmap.LockBits(rect,
                        ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
    
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = bmpData.Stride * bmpData.Height;
                    byte[] grayValues = new byte[bytes];
                    Marshal.Copy(ptr, grayValues, 0, bytes);
    
                    byte[] tempArray = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = 0;
                    }
    
                    switch (mode)
                    {
                        case 0:
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    List<byte> sortArray = new List<byte>();
                                    sortArray.Add(grayValues[(i - 1) * bmpData.Stride + j - 1]);
                                    sortArray.Add(grayValues[(i - 1) * bmpData.Stride + j]);
                                    sortArray.Add(grayValues[(i - 1) * bmpData.Stride + j + 1]);
                                    sortArray.Add(grayValues[i * bmpData.Stride + j - 1]);
                                    sortArray.Add(grayValues[i * bmpData.Stride + j]);
                                    sortArray.Add(grayValues[i * bmpData.Stride + j + 1]);
                                    sortArray.Add(grayValues[(i + 1) * bmpData.Stride + j - 1]);
                                    sortArray.Add(grayValues[(i + 1) * bmpData.Stride + j]);
                                    sortArray.Add(grayValues[(i + 1) * bmpData.Stride + j + 1]);
    
                                    sortArray.Sort();
                                    tempArray[i * bmpData.Stride + j] = sortArray[4];
                                }
                            }
                            break;
                        case 1:
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    List<byte> sortArray = new List<byte>();
                                    sortArray.Add(grayValues[(i - 2) * bmpData.Stride + j - 2]);
                                    sortArray.Add(grayValues[(i - 2) * bmpData.Stride + j - 1]);
                                    sortArray.Add(grayValues[(i - 2) * bmpData.Stride + j]);
                                    sortArray.Add(grayValues[(i - 2) * bmpData.Stride + j + 1]);
                                    sortArray.Add(grayValues[(i - 2) * bmpData.Stride + j + 2]);
                                    sortArray.Add(grayValues[(i - 1) * bmpData.Stride + j - 2]);
                                    sortArray.Add(grayValues[(i - 1) * bmpData.Stride + j - 1]);
                                    sortArray.Add(grayValues[(i - 1) * bmpData.Stride + j]);
                                    sortArray.Add(grayValues[(i - 1) * bmpData.Stride + j + 1]);
                                    sortArray.Add(grayValues[(i - 1) * bmpData.Stride + j + 2]);
                                    sortArray.Add(grayValues[i * bmpData.Stride + j - 2]);
                                    sortArray.Add(grayValues[i * bmpData.Stride + j - 1]);
                                    sortArray.Add(grayValues[i * bmpData.Stride + j]);
                                    sortArray.Add(grayValues[i * bmpData.Stride + j + 1]);
                                    sortArray.Add(grayValues[i * bmpData.Stride + j + 2]);
                                    sortArray.Add(grayValues[(i + 1) * bmpData.Stride + j - 2]);
                                    sortArray.Add(grayValues[(i + 1) * bmpData.Stride + j - 1]);
                                    sortArray.Add(grayValues[(i + 1) * bmpData.Stride + j]);
                                    sortArray.Add(grayValues[(i + 1) * bmpData.Stride + j + 1]);
                                    sortArray.Add(grayValues[(i + 1) * bmpData.Stride + j + 2]);
                                    sortArray.Add(grayValues[(i + 2) * bmpData.Stride + j - 2]);
                                    sortArray.Add(grayValues[(i + 2) * bmpData.Stride + j - 1]);
                                    sortArray.Add(grayValues[(i + 2) * bmpData.Stride + j]);
                                    sortArray.Add(grayValues[(i + 2) * bmpData.Stride + j + 1]);
                                    sortArray.Add(grayValues[(i + 2) * bmpData.Stride + j + 2]);
    
                                    sortArray.Sort();
                                    tempArray[i * bmpData.Stride + j] = sortArray[4];
                                }
                            }
                            break;
                        default:
                            break;
                    }
    
                    grayValues = (byte[])tempArray.Clone();
                    Marshal.Copy(grayValues, 0, ptr, bytes);
                    inputBitmap.UnlockBits(bmpData);
                    return inputBitmap;
                }
                catch
                {
                    return null;
                }
            }
            #endregion
    
            #region 图像锐化
            /// <summary>
            /// 图像锐化
            /// </summary>
            /// <param name="depth">
            /// 锐化的程序,分布在[0,1],值越大锐化程序越高      
            /// </param>
            /// <param name="inputBitmap">需要锐化的图像</param>
            /// <returns>锐化的结果图</returns>
            public static Bitmap ImageSharpen(double depth, Bitmap inputBitmap)
            {
                if (inputBitmap == null)
                    return null;
    
                if (depth < 0.0)
                    depth = 0.0;
                else if (depth > 1.0)
                    depth = 1.0;
    
                if (inputBitmap.PixelFormat == PixelFormat.Format24bppRgb)
                    inputBitmap = ToGray(inputBitmap);
    
                BitmapData srcData = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height),
                    ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
    
                IntPtr ptr = srcData.Scan0;
                int bytes = srcData.Stride * srcData.Height;
                byte[] grayValues = new byte[bytes];
                Marshal.Copy(ptr, grayValues, 0, bytes);
                //存储周边边缘的差值
                double temp;
    
                for (int i = 1; i < srcData.Height - 1; i++)
                {
                    for (int j = 1; j < srcData.Width - 1; j++)
                    {
                        temp = grayValues[i * srcData.Stride + j] -
                            ((grayValues[(i - 1) * srcData.Stride + j - 1] +
                            grayValues[(i - 1) * srcData.Stride + j] +
                            grayValues[(i - 1) * srcData.Stride + j + 1] +
                            grayValues[i * srcData.Stride + j - 1] +
                            grayValues[i * srcData.Stride + j + 1] +
                            grayValues[(i + 1) * srcData.Stride + j - 1] +
                            grayValues[(i + 1) * srcData.Stride + j] +
                            grayValues[(i + 1) * srcData.Stride + j + 1])) / 8;
                        if (temp < 0.0)
                            temp = 0.0;
                        grayValues[i * srcData.Stride + j] -= Convert.ToByte(temp * depth);
    
                    }
                }
    
                Marshal.Copy(grayValues, 0, ptr, bytes);
                inputBitmap.UnlockBits(srcData);
                return inputBitmap;
    
            }
            #endregion
    
            #region 图像膨胀函数
            /// <summary>
            /// 图像膨胀函数
            /// </summary>
            /// <param name="mode">结构元素
            /// 0:3位水平方向的结构元素
            /// 1:5位水平方向的结构元素
            /// 2:3位垂直方向的结构元素
            /// 3:5位垂直方向的结构元素
            /// 4:3位十字状结构元素
            /// 5:5位十字状结构元素
            /// 6:3位方形结构元素
            /// 7:5位方形结构元素
            /// </param>       
            /// <param name="inputBitmap">需要膨胀的图像</param>
            /// <returns>返回膨胀后的图像</returns>
            public static Bitmap ImageDilate(int mode, Bitmap inputBitmap)
            {
                try
                {
                    //先以255作为阈值分割点           
                    inputBitmap = ToGray(inputBitmap);
                    inputBitmap = ToBinary(255, inputBitmap);
    
    
                    Rectangle rect = new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height);
                    //以读写的方式锁定全部位图像素
                    System.Drawing.Imaging.BitmapData bmpData = inputBitmap.LockBits(rect,
                        System.Drawing.Imaging.ImageLockMode.ReadWrite,
                        PixelFormat.Format8bppIndexed);
                    IntPtr ptr = bmpData.Scan0;
    
                    //将图像数据复制到数组中,用于膨胀操作
                    int bytes = bmpData.Stride * bmpData.Height;
                    byte[] grayValues = new byte[bytes];
                    Marshal.Copy(ptr, grayValues, 0, bytes);
    
                    //设置临时数组,用来存储膨胀操作的结果
                    byte[] tempArray = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                        tempArray[i] = 0;
    
                    switch (mode)
                    {
                            //3位水平方向的结构元素
                        case 0:
                            for (int i = 0; i < bmpData.Height; i++)
                            {
                                for (int j = 1; j < bmpData.Width-1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255)
                                        tempArray[i * bmpData.Stride + j] = 255;
                                }
                            }
                            break;
    
                            //5位水平方向的结构元素
                        case 1:
                            for (int i = 0; i < bmpData.Height; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 2] == 255)
                                        tempArray[i * bmpData.Stride + j] = 255;
                                }
                            }
                            break;
    
                            //3位垂直方向的结构元素
                        case 2:
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255)
                                        tempArray[i * bmpData.Stride + j] = 255;
                                }
                            }
                            break;
    
                            //5位垂直方向的结构元素
                        case 3:
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j] == 255)
                                        tempArray[i * bmpData.Stride + j] = 255;
                                }
                            }
                            break;
    
                            //3位十字形状结构元素
                        case 4:
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255)
                                        tempArray[i * bmpData.Stride + j] = 255;
                                }
                            }
                            break;
    
                            //5位十字形状结构元素
                        case 5:
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 2] == 255)
                                        tempArray[i * bmpData.Stride + j] = 255;
                                }
                            }
                            break;
    
                            //3位方形结构元素
                        case 6:
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j + 1] == 255)
                                        tempArray[i * bmpData.Stride + j] = 255;
                                }
                            }
                            break;
    
                            //5位方形结构元素
                        case 7:
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[(i - 2) * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j + 2] == 255)
                                        tempArray[i * bmpData.Stride + j] = 255;
                                }
                            }
                            break;
    
                        default:
                            break;
    
                    }
    
                    grayValues = (byte[])tempArray.Clone();
                    Marshal.Copy(grayValues, 0, ptr, bytes);
                    inputBitmap.UnlockBits(bmpData);
                    return inputBitmap;
                }
                catch
                {
                    return null;
                }
                
            }
            #endregion      
    
            #region 图像开运算
            /// <summary>
            /// 图像开运算
            /// </summary>
            /// <param name="mode">结构元素
            /// 0:3位水平方向的结构元素
            /// 1:5位水平方向的结构元素
            /// 2:3位垂直方向的结构元素
            /// 3:5位垂直方向的结构元素
            /// 4:3位十字状结构元素
            /// 5:5位十字状结构元素
            /// 6:3位方形结构元素
            /// 7:5位方形结构元素
            /// </param>
            /// <param name="inputBitmap">需要开运算的图像</param>
            /// <returns>开运算后的图像</returns>
            public static Bitmap ImageOpening(int mode, Bitmap inputBitmap)
            {
                try
                {
                    //先以255作为阈值分割点
                    inputBitmap = ToGray(inputBitmap);
                    inputBitmap = ToBinary(255, inputBitmap);
    
                    Rectangle rect = new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = inputBitmap.LockBits(rect,
                        System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = bmpData.Stride * bmpData.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
    
    
                    byte[] temp1Array = new byte[bytes];
                    byte[] tempArray = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = temp1Array[i] = 0;
                    }
    
                    switch (mode)
                    {
                        case 0:
                            //3位水平结构元素
                            //腐蚀运算
                            for (int i = 0; i < bmpData.Height; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 1] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //膨胀运算
                            for (int i = 0; i < bmpData.Stride; i++)
                            {
                                for (int j = 1; j < bmpData.Stride - 1; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 1] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 1:
                            //5位水平结构元素
                            //腐蚀运算
                            for (int i = 0; i < bmpData.Height; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 2] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 2] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //膨胀运算
                            for (int i = 0; i < bmpData.Height; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 2] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 2] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 2:
                            //3位垂直结构元素
                            //腐蚀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //膨胀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 3:
                            //5位垂直结构元素
                            //腐蚀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 2) * bmpData.Stride + j] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //膨胀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 2) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 2) * bmpData.Stride + j] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 4:
                            //3位十字形结构元素
                            //腐蚀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 1] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //膨胀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 1] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 5:
                            //5位十字形结构元素
                            //腐蚀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 2) * bmpData.Stride + j] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 2] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 2] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //膨胀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 2) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 2) * bmpData.Stride + j] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 2] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 2] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 6:
                            //3位方形结构元素
                            //腐蚀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j + 1] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //膨胀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j + 1] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 7:
                            //5位方形结构元素
                            //腐蚀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[(i - 2) * bmpData.Stride + j - 2] == 255 &&
                                        grayValues[(i - 2) * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 2) * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[(i - 2) * bmpData.Stride + j + 2] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j - 2] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[(i - 1) * bmpData.Stride + j + 2] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 2] == 255 &&
                                        grayValues[i * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[i * bmpData.Stride + j + 2] == 255 &&
                                        grayValues[(i + 2) * bmpData.Stride + j - 2] == 255 &&
                                        grayValues[(i + 2) * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[(i + 2) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 2) * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[(i + 2) * bmpData.Stride + j + 2] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j - 2] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j - 1] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j + 1] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j + 2] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //膨胀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (temp1Array[(i - 2) * bmpData.Stride + j - 2] == 255 ||
                                        temp1Array[(i - 2) * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[(i - 2) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 2) * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[(i - 2) * bmpData.Stride + j + 2] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j - 2] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[(i - 1) * bmpData.Stride + j + 2] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 2] == 255 ||
                                        temp1Array[i * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[i * bmpData.Stride + j + 2] == 255 ||
                                        temp1Array[(i + 2) * bmpData.Stride + j - 2] == 255 ||
                                        temp1Array[(i + 2) * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[(i + 2) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 2) * bmpData.Stride + j + 1] == 25 ||
                                        temp1Array[(i + 2) * bmpData.Stride + j + 2] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j - 2] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j - 1] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j + 1] == 255 ||
                                        temp1Array[(i + 1) * bmpData.Stride + j + 2] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        default:
                            break;
                    }
    
    
                    grayValues = (byte[])tempArray.Clone();
    
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    inputBitmap.UnlockBits(bmpData);
                    return inputBitmap;
    
                }
                catch
                {
                    return null;
                }
                
            }
            #endregion
    
            #region 图像闭运算
            /// <summary>
            /// 图像闭运算
            /// </summary>
            /// <param name="mode">结构元素
            /// 0:3位水平方向的结构元素
            /// 1:5位水平方向的结构元素
            /// 2:3位垂直方向的结构元素
            /// 3:5位垂直方向的结构元素
            /// 4:3位十字状结构元素
            /// 5:5位十字状结构元素
            /// 6:3位方形结构元素
            /// 7:5位方形结构元素
            /// </param>
            /// <param name="inputBitmap">需要闭运算的图像</param>
            /// <returns>闭运算后的结果</returns>
            public static Bitmap ImageClosing(int mode, Bitmap inputBitmap)
            {
                try
                {
                    //先以255作为阈值分割点
                    inputBitmap = ToGray(inputBitmap);
                    inputBitmap = ToBinary(255, inputBitmap);
    
                    Rectangle rect = new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height);
                    System.Drawing.Imaging.BitmapData bmpData = inputBitmap.LockBits(rect,
                        System.Drawing.Imaging.ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
                    IntPtr ptr = bmpData.Scan0;
                    int bytes = bmpData.Stride * bmpData.Height;
                    byte[] grayValues = new byte[bytes];
                    System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);
    
    
                    byte[] temp1Array = new byte[bytes];
                    byte[] tempArray = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        tempArray[i] = temp1Array[i] = 0;
                    }
    
                    switch (mode)
                    {
                        case 0:
                            //3位水平结构元素
                            //膨胀运算
                            for (int i = 0; i < bmpData.Height; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //腐蚀运算
                            for (int i = 0; i < bmpData.Stride; i++)
                            {
                                for (int j = 1; j < bmpData.Stride - 1; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 1] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 1:
                            //5位水平结构元素
                            //膨胀运算
                            for (int i = 0; i < bmpData.Height; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 2] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //腐蚀运算
                            for (int i = 0; i < bmpData.Height; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 2] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 2] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 2:
                            //3位垂直结构元素
                            //膨胀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //腐蚀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 3:
                            //5位垂直结构元素
                            //膨胀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //腐蚀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 0; j < bmpData.Width; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 2) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 2) * bmpData.Stride + j] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 4:
                            //3位十字形结构元素
                            //膨胀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //腐蚀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 1] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 5:
                            //5位十字形结构元素
                            //膨胀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 2] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //腐蚀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 2) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 2) * bmpData.Stride + j] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 2] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 2] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 6:
                            //3位方形结构元素
                            //膨胀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j + 1] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //腐蚀运算
                            for (int i = 1; i < bmpData.Height - 1; i++)
                            {
                                for (int j = 1; j < bmpData.Width - 1; j++)
                                {
                                    if (temp1Array[i * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j + 1] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        case 7:
                            //5位方形结构元素
                            //膨胀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (grayValues[(i - 2) * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i - 2) * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i - 1) * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[i * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[i * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i + 2) * bmpData.Stride + j + 2] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j - 2] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j - 1] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j] == 255 &&
                                        grayValues[(i + 1) * bmpData.Stride + j + 1] == 255 ||
                                        grayValues[(i + 1) * bmpData.Stride + j + 2] == 255)
                                    {
                                        temp1Array[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            //腐蚀运算
                            for (int i = 2; i < bmpData.Height - 2; i++)
                            {
                                for (int j = 2; j < bmpData.Width - 2; j++)
                                {
                                    if (temp1Array[(i - 2) * bmpData.Stride + j - 2] == 255 &&
                                        temp1Array[(i - 2) * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[(i - 2) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 2) * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[(i - 2) * bmpData.Stride + j + 2] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j - 2] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[(i - 1) * bmpData.Stride + j + 2] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 2] == 255 &&
                                        temp1Array[i * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[i * bmpData.Stride + j + 2] == 255 &&
                                        temp1Array[(i + 2) * bmpData.Stride + j - 2] == 255 &&
                                        temp1Array[(i + 2) * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[(i + 2) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 2) * bmpData.Stride + j + 1] == 25 &&
                                        temp1Array[(i + 2) * bmpData.Stride + j + 2] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j - 2] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j - 1] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j + 1] == 255 &&
                                        temp1Array[(i + 1) * bmpData.Stride + j + 2] == 255)
                                    {
                                        tempArray[i * bmpData.Stride + j] = 255;
                                    }
    
                                }
                            }
                            break;
                        default:
                            break;
                    }
    
                    grayValues = (byte[])tempArray.Clone();
    
                    System.Runtime.InteropServices.Marshal.Copy(grayValues, 0, ptr, bytes);
                    inputBitmap.UnlockBits(bmpData);
                    return inputBitmap;
    
                }
                catch
                {
                    return null;
                }
            }
            #endregion
    
            
    
    
        }
    
  • 相关阅读:
    mysql字符集和数据库引擎修改方法
    android 之GridView和ImageView教程
    把php代码保存到php文件实现方法
    extjs gridpanel 操作行 得到选中行的列
    SQL 分页
    vs 调试 慢 解决办法
    JS获取屏幕高度
    C#事件以及委托
    ExtJs 3.0 不兼容 IE9
    ASP.NET 获取客户端IP (无视代理)
  • 原文地址:https://www.cnblogs.com/yuchao/p/1864457.html
Copyright © 2020-2023  润新知