C#图像处理程序实现--Canny实现 笔记整理(其中的非极大值抑制点)

在Canny算法中,对于其中的非极大值抑制这一点做笔记整理,过程看之前的这一片,注意理解里面的关于梯度相关的概念

原理如下:(需要理解)
依据当前点的周围点的梯度模来推算中心点的模,然后与实际值比较,若小则保留,若大于实际值则舍弃,在边缘检测中也有根据梯度模确定是否边缘,大于一定阈值就判定为是!
由中心点的梯度向量、周围点的梯度模,推断中心点的梯度模,再与实际值比较,梯度模就是梯度程度!
在这里插入图片描述

已知ax,ay,a1,a2,求Cm,如下:
在这里插入图片描述

用a0与cm,cm’比较确定是否舍弃a0,转90度再计算一次;
在这里插入图片描述推导如上,下面来看一下代码:

在这里插入代码片
​        public static Bitmap NoNMaximumSupressionOri(this Bitmap sourceBitmap)
        {
            double factor = 1;
            int[,] filterMatrixx = new int[3, 3] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } };//in X direction
            int[,] YfilterMatrixy = new int[3, 3] { { 1, 2, 1 }, { 0, 0, 0 }, { -1, -2, -1 } };//in Y direction
            if ((filterMatrixx.GetLength(0) & 1) == 0 || (filterMatrixx.GetLength(1) & 1) == 0 || filterMatrixx.GetLength(0) != filterMatrixx.GetLength(1))
                return null;
            double[,] data = ToGrayBufferD<double>(sourceBitmap);
            int height = data.GetLength(0);
            int width = data.GetLength(1);
            int filterOffset = (filterMatrixx.GetLength(1) - 1) / 2;
            double[,] dx = new double[height, width];
            double[,] dy = new double[height, width];
            double[,] dxy = new double[height, width];
            double[,] mag = new double[height, width];
            double[,] output = new double[height, width];
            unsafe
            {
                int toffset = filterOffset * width;
                fixed (double* source = data, pdx = dx, pdy = dy, pdxy = dxy, pm = mag)
                {
                    double* src = source + toffset, Dx = pdx + toffset, Dy = pdy + toffset, Dxy = pdxy + toffset, Dm = pm + toffset;
                    double a11, a12, a13, a21, a23, a31, a32, a33, h, v;

                    for (int i = filterOffset; i < height - filterOffset; i++)
                    {
                        src += filterOffset;
                        Dx += filterOffset;
                        Dy += filterOffset;
                        Dxy += filterOffset;
                        Dm += filterOffset;
                        for (int j = filterOffset; j < width - filterOffset; j++, src++, Dx++, Dy++, Dxy++, Dm++)
                        {

                            a11 = src[+width + 1]; a12 = src[+1]; a13 = src[-width + 1];
                            a21 = src[+width + 0]; /*  a22    */  a23 = src[-width + 0];
                            a31 = src[+width - 1]; a32 = src[-1]; a33 = src[-width - 1];

                            h = ((a11 + a12 + a13) - (a31 + a32 + a33)) * 0.166666667f;

                            v = ((a11 + a21 + a31) - (a13 + a23 + a33)) * 0.166666667f;

                            *Dx = h;
                            *Dy = v;
                            *Dxy = h * v;
                            *Dm = Math.Sqrt((*Dx * *Dx) + (*Dy * *Dy));

                        }
                        src += filterOffset;
                        Dx += filterOffset;
                        Dy += filterOffset;
                        Dxy += filterOffset;
                        Dm += filterOffset;
                    }
                }
                double a1, a2, b1, b2, A, B, point, val, max = 0;
                int cdx, cdy;
                fixed (double* pdx = dx, pdy = dy, pm = mag, pout = output)
                {
                    double* Dx = pdx + toffset, Dy = pdy + toffset, Dout = pout + toffset, Dm = pm + toffset;
                    for (int i = filterOffset; i < height - filterOffset; i++)
                    {
                        Dout += filterOffset;
                        Dx += filterOffset;
                        Dy += filterOffset;
                        Dm += filterOffset;
                        for (int j = filterOffset; j < width - filterOffset; j++, Dx++, Dy++, Dm++, Dout++)
                        {
                            cdx = *Dx > 0 ? 1 : -1;
                            cdy = *Dy > 0 ? 1 : -1;
                            if (Math.Abs(*Dx) > Math.Abs(*Dy))
                            {
                                a1 = Dm[cdx];
                                a2 = Dm[cdx - cdy * width];
                                b1 = Dm[-cdx];
                                b2 = Dm[-cdx + cdy * width];
                                A = (Math.Abs(*Dx) - Math.Abs(*Dy)) * a1 + Math.Abs(*Dy) * a2;
                                B = (Math.Abs(*Dx) - Math.Abs(*Dy)) * b1 + Math.Abs(*Dy) * b2;
                                point = *Dm * Math.Abs(*Dx);
                                if (point >= A && point > B)
                                    *Dout = Math.Abs(*Dx);
                                else
                                    *Dout = 0;
                            }
                            else
                            {
                                a1 = Dm[-cdy * width];
                                a2 = Dm[cdx - cdy * width];
                                b1 = Dm[cdy * width];
                                b2 = Dm[-cdx + cdy * width];
                                A = (Math.Abs(*Dy) - Math.Abs(*Dx)) * a1 + Math.Abs(*Dx) * a2;
                                B = (Math.Abs(*Dy) - Math.Abs(*Dx)) * b1 + Math.Abs(*Dx) * b2;
                                point = *Dm * Math.Abs(*Dy);
                                if (point >= A && point > B)
                                    *Dout = Math.Abs(*Dy);
                                else
                                    *Dout = 0;
                            }
                            if (*Dout > max)
                                max = *Dout;
                        }
                        Dout += filterOffset;
                        Dx += filterOffset;
                        Dy += filterOffset;
                        Dm += filterOffset;
                    }
                }
                double ratio = 255 / max;
                fixed (double* pout = output)
                {
                    double* Dout = pout + toffset;
                    for (int i = filterOffset; i < height - filterOffset; i++)
                    {
                        Dout += filterOffset;
                        for (int j = filterOffset; j < width - filterOffset; j++, Dout++)
                        {
                            *Dout *= ratio;
                        }
                        Dout += filterOffset;
                    }
                }
            }
            Bitmap resultBitmap = GetBmpFromArray<double>(output);
            return resultBitmap;
        }

这里做简要解释:
在这里插入图片描述
代码附上,下载学习

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值