zoukankan      html  css  js  c++  java
  • Sobel算法

    最近看了一些Sobel算法,并试了一下,源码如下:

    private void Sobel(Bitmap img) {
                int width = img.Width;
                int height = img.Height;
    
                int[,] Gx = new int[3, 3]{ {-1, 0, 1 },
                                           {-2, 0, 2 } ,
                                           {-1, 0, 1 } };
    
                int[,] Gy = new int[3, 3]{ {-1,-2,-1},
                                           { 0, 0, 0 },
                                           { 1, 2, 1}};
    
                int[,] TotalGx = new int[img.Width, img.Height];
                int[,] TotalGy = new int[img.Width, img.Height];
                int[,] GTotal = new int[img.Width, img.Height];
    
    
                Bitmap bitmapTemp = new Bitmap(img.Width, img.Height, PixelFormat.Format24bppRgb);
                
                LockBitmap lockBitmap1 = new LockBitmap(bitmapTemp);
                lockBitmap1.LockBits();
    
    
                LockBitmap lockBitmap = new LockBitmap(img);
                lockBitmap.LockBits();
                for (int i = 1; i < img.Width - 1; i++)
                {
                    for (int j = 1; j < img.Height - 1; j++)
                    {
                        Color a = lockBitmap.GetPixel(i - 1, j - 1);//[0][0]
                        Color b = lockBitmap.GetPixel(i - 1, j);    //[0][1]
                        Color c = lockBitmap.GetPixel(i - 1, j + 1);//[0][2]
                        
                        Color d = lockBitmap.GetPixel(i, j - 1);    //[1][0]
                        Color f = lockBitmap.GetPixel(i, j);        //[1][1]
                        Color g = lockBitmap.GetPixel(i, j + 1);    //[1][2]
    
                        Color h = lockBitmap.GetPixel(i + 1, j - 1);//[2][0]
                        Color l = lockBitmap.GetPixel(i + 1, j);    //[2][1]
                        Color n = lockBitmap.GetPixel(i + 1, j + 1); //[2][2]
    
    
                        TotalGx[i, j] = Gx[0, 0] * Avg(a) + Gx[0, 1] * Avg(b) + Gx[0, 2] * Avg(c)
                                       + Gx[1, 0] * Avg(d) + Gx[1, 1] * Avg(f) + Gx[1, 2] * Avg(g)
                                       + Gx[2, 0] * Avg(h) + Gx[2, 1] * Avg(l) + Gx[2, 2] * Avg(n);
    
    
    
    
                        //if (TotalGx[i, j] < 0) { TotalGx[i, j] = 0; }
                        //if (TotalGx[i, j] > 255) { TotalGx[i, j] = 255; }
    
                        TotalGy[i, j] = Gy[0, 0] * Avg(a) + Gy[0, 1] * Avg(b) + Gy[0, 2] * Avg(c)
                                      + Gy[1, 0] * Avg(d) + Gy[1, 1] * Avg(f) + Gy[1, 2] * Avg(g)
                                      + Gy[2, 0] * Avg(h) + Gy[2, 1] * Avg(l) + Gy[2, 2] * Avg(n);
    
    
                        //if (TotalGy[i, j] < 0) { TotalGy[i, j] = 0; }
                        //if (TotalGy[i, j] > 255) { TotalGy[i, j] = 255; }
    
    
    
                        //GTotal[i, j] = TotalGx[i, j] + TotalGy[i, j];
                        GTotal[i, j] = (int)Math.Sqrt(TotalGx[i, j] * TotalGx[i, j] + TotalGy[i, j] * TotalGy[i, j]);
    
                        if (GTotal[i, j] >= 255)
                        { GTotal[i, j] = 255; }
    
                        if (GTotal[i, j] < 0)
                        { GTotal[i, j] = 0; }
                        //bitmapTemp.SetPixel(i, j, Color.FromArgb(GTotal[i, j], GTotal[i ,j], GTotal[i, j]));
                        lockBitmap1.SetPixel(i, j, Color.FromArgb(GTotal[i, j], GTotal[i, j], GTotal[i, j]));
                    }
                }
                lockBitmap1.UnlockBits();
                lockBitmap.UnlockBits();
                pictureBox2.Image = lockBitmap1.GetBitmap();
    
            }
    public class LockBitmap
        {
            Bitmap source = null;
            IntPtr Iptr = IntPtr.Zero;
            BitmapData bitmapData = null;
    
            public byte[] Pixels { get; set; }
            public int Depth { get; private set; }
            public int Width { get; private set; }
            public int Height { get; private set; }
    
            public LockBitmap(Bitmap source)
            {
                this.source = source;
            }
    
            public Bitmap GetBitmap() { return this.source; }
    
            /// <summary>
            /// Lock bitmap data
            /// </summary>
            public void LockBits()
            {
                try
                {
                    // Get width and height of bitmap
                    Width = source.Width;
                    Height = source.Height;
    
                    // get total locked pixels count
                    int PixelCount = Width * Height;
    
                    // Create rectangle to lock
                    Rectangle rect = new Rectangle(0, 0, Width, Height);
    
                    // get source bitmap pixel format size
                    Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);
    
                    // Check if bpp (Bits Per Pixel) is 8, 24, or 32
                    if (Depth != 8 && Depth != 24 && Depth != 32)
                    {
                        throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
                    }
    
                    // Lock bitmap and return bitmap data
                    bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,
                                                 source.PixelFormat);
    
                    // create byte array to copy pixel values
                    int step = Depth / 8;
                    Pixels = new byte[PixelCount * step];
                    Iptr = bitmapData.Scan0;
    
                    // Copy data from pointer to array
                    Marshal.Copy(Iptr, Pixels, 0, Pixels.Length);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
    
            /// <summary>
            /// Unlock bitmap data
            /// </summary>
            public void UnlockBits()
            {
                try
                {
                    // Copy data from byte array to pointer
                    Marshal.Copy(Pixels, 0, Iptr, Pixels.Length);
    
                    // Unlock bitmap data
                    source.UnlockBits(bitmapData);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
            /// <summary>
            /// Get the color of the specified pixel
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <returns></returns>
            public Color GetPixel(int x, int y)
            {
                Color clr = Color.Empty;
    
                // Get color components count
                int cCount = Depth / 8;
    
                // Get start index of the specified pixel
                int i = ((y * Width) + x) * cCount;
    
                if (i > Pixels.Length - cCount)
                    throw new IndexOutOfRangeException();
    
                if (Depth == 32) // For 32 bpp get Red, Green, Blue and Alpha
                {
                    byte b = Pixels[i];
                    byte g = Pixels[i + 1];
                    byte r = Pixels[i + 2];
                    byte a = Pixels[i + 3]; // a
                    clr = Color.FromArgb(a, r, g, b);
                }
                if (Depth == 24) // For 24 bpp get Red, Green and Blue
                {
                    byte b = Pixels[i];
                    byte g = Pixels[i + 1];
                    byte r = Pixels[i + 2];
                    clr = Color.FromArgb(r, g, b);
                }
                if (Depth == 8)
                // For 8 bpp get color value (Red, Green and Blue values are the same)
                {
                    byte c = Pixels[i];
                    clr = Color.FromArgb(c, c, c);
                }
                return clr;
            }
    
            /// <summary>
            /// Set the color of the specified pixel
            /// </summary>
            /// <param name="x"></param>
            /// <param name="y"></param>
            /// <param name="color"></param>
            public void SetPixel(int x, int y, Color color)
            {
                // Get color components count
                int cCount = Depth / 8;
    
                // Get start index of the specified pixel
                int i = ((y * Width) + x) * cCount;
    
                if (Depth == 32) // For 32 bpp set Red, Green, Blue and Alpha
                {
                    Pixels[i] = color.B;
                    Pixels[i + 1] = color.G;
                    Pixels[i + 2] = color.R;
                    Pixels[i + 3] = color.A;
                }
                if (Depth == 24) // For 24 bpp set Red, Green and Blue
                {
                    Pixels[i] = color.B;
                    Pixels[i + 1] = color.G;
                    Pixels[i + 2] = color.R;
                }
                if (Depth == 8)
                // For 8 bpp set color value (Red, Green and Blue values are the same)
                {
                    Pixels[i] = color.B;
                }
            }
    
            //public Color GetPixel(int x, int y)
            //{
            //    unsafe
            //    {
            //        byte* ptr = (byte*)Iptr;
            //        ptr = ptr + bitmapData.Stride * y;
            //        ptr += Depth * x / 8;
            //        Color c = Color.Empty;
            //        if (Depth == 32)
            //        {
            //            int a = ptr[3];
            //            int r = ptr[2];
            //            int g = ptr[1];
            //            int b = ptr[0];
            //            c = Color.FromArgb(a, r, g, b);
            //        }
            //        else if (Depth == 24)
            //        {
            //            int r = ptr[2];
            //            int g = ptr[1];
            //            int b = ptr[0];
            //            c = Color.FromArgb(r, g, b);
            //        }
            //        else if (Depth == 8)
            //        {
            //            int r = ptr[0];
            //            c = Color.FromArgb(r, r, r);
            //        }
            //        return c;
            //    }
            //}
    
            //public void SetPixel(int x, int y, Color c)
            //{
            //    unsafe
            //    {
            //        byte* ptr = (byte*)Iptr;
            //        ptr = ptr + bitmapData.Stride * y;
            //        ptr += Depth * x / 8;
            //        if (Depth == 32)
            //        {
            //            ptr[3] = c.A;
            //            ptr[2] = c.R;
            //            ptr[1] = c.G;
            //            ptr[0] = c.B;
            //        }
            //        else if (Depth == 24)
            //        {
            //            ptr[2] = c.R;
            //            ptr[1] = c.G;
            //            ptr[0] = c.B;
            //        }
            //        else if (Depth == 8)
            //        {
            //            ptr[2] = c.R;
            //            ptr[1] = c.G;
            //            ptr[0] = c.B;
            //        }
            //    }
            //}
    
    
    
            //return data[((width * y) + x) * 4 + i];
        }

    效果如下:

    总结:用自带的图片处理性能低下,建议使用指针或者其他图像库处理,比如OpenCV的.NET库。

  • 相关阅读:
    docker--docker介绍
    docker--虚拟化
    高级运维工程师的打怪升级之路
    mysql常用函数
    CentOS 7 下使用 Firewall
    51nod 1094 和为k的连续区间(map+前缀和)
    51nod 1092 回文字符串(dp)
    51nod 1062 序列中最大的数(打表预处理)
    51nod 1284 2 3 5 7的倍数(容斥原理+反面思考)
    51nod 1347 旋转字符串(思维好题)
  • 原文地址:https://www.cnblogs.com/RainbowInTheSky/p/8940321.html
Copyright © 2011-2022 走看看