C#边沿检测sobel方法

 //
            BitmapData bmData = m_Bitmap.LockBits(new Rectangle(0, 0, m_Bitmap.Width, m_Bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            float valve = 50;
            for (int i = 0; i < 256; i++)
                gray[i] = 0;

            unsafe
            {
                int stride = bmData.Stride;
                System.IntPtr Scan0 = bmData.Scan0;
                byte* p = (byte*)(void*)Scan0;
                byte* pp;
                int tt;
                int nOffset = stride - m_Bitmap.Width * 3;
                int nWidth = m_Bitmap.Width;
                int nHeight = m_Bitmap.Height;
                int Sx = 0;
                int Sy = 0;
                //	float max = 0;
                double sumM = 0;
                double sumCount = 0;
                int[] marginalMx = { -1, 0, 1, -2, 0, 2, -1, 0, 1 };   //sobel模板
                int[] marginalMy = { 1, 2, 1, 0, 0, 0, -1, -2, -1 };
                int[,] dlta = new int[nHeight, nWidth];
                for (int y = 0; y < nHeight; ++y)      //sobel算子
                {
                    for (int x = 0; x < nWidth; ++x)
                    {
                        if (!(x <= 0 || x >= nWidth - 1 || y <= 0 || y >= nHeight - 1))//该过
                        {
                            pp = p;
                            Sx = 0;
                            Sy = 0;
                            for (int i = -1; i <= 1; i++)
                                for (int j = -1; j <= 1; j++)
                                {
                                    pp += (j * 3 + stride * i);
                                    Sx += pp[0] * marginalMx[(i + 1) * 3 + j + 1];
                                    Sy += pp[0] * marginalMy[(i + 1) * 3 + j + 1];
                                    pp = p;
                                }
                            m[y, x] = (int)(Math.Sqrt(Sx * Sx + Sy * Sy));
                            if (m[y, x] > valve / 2) //增强白点
                            {
                                if (p[0] > 240)
                                {
                                    m[y, x] += valve;
                                }
                                else if (p[0] > 220)
                                {
                                    m[y, x] += (float)(valve * 0.8);
                                }
                                else if (p[0] > 200)
                                {
                                    m[y, x] += (float)(valve * 0.6);
                                }
                                else if (p[0] > 180)
                                {
                                    m[y, x] += (float)(valve * 0.4);
                                }
                                else if (p[0] > 160)
                                {
                                    m[y, x] += (float)(valve * 0.2);
                                }
                            }
                            float tan;
                            if (Sx != 0)
                            {
                                tan = Sy / Sx;
                            }
                            else tan = 10000;
                            if (-0.41421356 <= tan && tan < 0.41421356)//角度为-22.5度到22.5度之间
                            {
                                dlta[y, x] = 0; //	m[y,x]+=valve;                                 
                            }
                            else if (0.41421356 <= tan && tan < 2.41421356)//角度为22.5度到67.5度之间
                            {
                                dlta[y, x] = 1; //m[y,x] = 0;
                            }
                            else if (tan >= 2.41421356 || tan < -2.41421356)//角度为67.5度到90度之间或-90度到-67.5度
                            {
                                dlta[y, x] = 2;    //	m[y,x]+=valve;
                            }
                            else
                            {
                                dlta[y, x] = 3;//m[y,x] = 0;     
                            }
                        }
                        else
                            m[y, x] = 0;
                        p += 3;
                        if (m[y, x] > 0)
                        {
                            sumCount++;
                            sumM += m[y, x];
                        }
                    }
                    p += nOffset;
                }
                unsafe
                {
                    p = (byte*)(void*)Scan0; //非极大值抑制和阀值
                    for (int y = 0; y < nHeight; ++y)
                    {
                        for (int x = 0; x < nWidth; ++x)
                        {
                            if (m[y, x] > sumM / sumCount * 1.2)
                            {
                                p[0] = p[1] = p[2] = (byte)(m[y, x]); //m[y,x]=1;                            
                            }
                            else
                            {
                                m[y, x] = 0;
                                p[0] = p[1] = p[2] = 0;
                            }
                            if (x >= 1 && x <= nWidth - 1 && y >= 1 && y <= nHeight - 1 && m[y, x] > valve)
                            {
                                switch (dlta[y, x])
                                {
                                    case 0:
                                        if (m[y, x] >= m[y, x - 1] && m[y, x] >= m[y, x + 1])//水平边缘
                                        {
                                            p[0] = p[1] = p[2] = 255;
                                        }
                                        break;

                                    case 1:
                                        if (m[y, x] >= m[y + 1, x - 1] && m[y, x] >= m[y - 1, x + 1])//正斜45度边缘
                                        {
                                            p[0] = p[1] = p[2] = 255;
                                        }
                                        break;

                                    case 2:
                                        if (m[y, x] >= m[y - 1, x] && m[y, x] >= m[y + 1, x])//垂直边缘
                                        {
                                            p[0] = p[1] = p[2] = 255;
                                        }
                                        break;

                                    case 3:
                                        if (m[y, x] >= m[y + 1, x + 1] && m[y, x] >= m[y - 1, x - 1])//反斜45度边缘
                                        {
                                            p[0] = p[1] = p[2] = 255;
                                        }
                                        break;
                                }
                            }
                            if (p[0] == 255)
                            {
                                m[y, x] = 1;
                            }
                            else
                            {
                                m[y, x] = 0;
                                p[0] = p[1] = p[2] = 0;
                            }

                            tt = p[0];
                            gray[tt]++;
                            p += 3;
                        }
                        //  p += nOffset;
                    }
                    m_Bitmap.UnlockBits(bmData);
                    
                }
            }
            pictureBox1.Image = m_Bitmap;

来源GitHub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

稻田里展望者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值