• canny算子求图像边缘,edgebox那部分


     过程:

        1.      彩色图像转换为灰度图像

      彩色转灰度图公式:

      gray  =  R * 0.299 + G * 0.587 + B * 0.114
        2.      对图像进行高斯模糊
        3.      计算图像梯度,根据梯度计算图像边缘幅值与角度(这里其实用到了微分边缘检测算子来计算梯度幅值方向)

    求每个点x,y两个方向的梯度,这个地方是按照Sobel滤波器的方式(这个是opecv官方这么写的,有些博客也没有使用sobel的滤波器,使用的其他的)

    根据x、y两个方向的梯度求幅值与角度


        4.      非最大信号压制处理(边缘细化) 

    算出的角度应该是[-π/2,π/2],加上π/2变成0到π的范围,然后把角度分成4个区域。

    每个点得到角度之后,根据自身的角度比较中心像素角度上相邻两个像素,如果中心像素小于其中任意一个,则舍弃该边缘像素点,否则保留,代码如下:

    // 非最大信号压制算法 3x3
    Arrays.fill(magnitudes, 0);
    for (int row = 0; row < height; row++) {
        for (int col = 0; col < width; col++) {
            index = row * width + col;
            float angle = magnitudes[index];
            float m0 = data[index];
            magnitudes[index] = m0;
            if(angle >=0 && angle < 22.5) // angle 0
            {
                float m1 = getPixel(data, width, height, col-1, row);
                float m2 = getPixel(data, width, height, col+1, row);
                if(m0 < m1 || m0 < m2)
                {
                    magnitudes[index] = 0;
                }
            }
            else if(angle >= 22.5 && angle < 67.5) // angle +45
            {
                float m1 = getPixel(data, width, height, col+1, row-1);
                float m2 = getPixel(data, width, height, col-1, row+1);
                if(m0 < m1 || m0 < m2)
                {
                    magnitudes[index] = 0;
                }
            }
            else if(angle >= 67.5 && angle < 112.5) // angle 90
            {
                float m1 = getPixel(data, width, height, col, row+1);
                float m2 = getPixel(data, width, height, col, row-1);
                if(m0 < m1 || m0 < m2)
                {
                    magnitudes[index] = 0;
                }
            }
            else if(angle >=112.5 && angle < 157.5) // angle 135 / -45
            {
                float m1 = getPixel(data, width, height, col-1, row-1);
                float m2 = getPixel(data, width, height, col+1, row+1);
                if(m0 < m1 || m0 < m2)
                {
                    magnitudes[index] = 0;
                }
            }
            else if(angle >=157.5) // 跟零度是一样的
            {
                float m1 = getPixel(data, width, height, col+1, row);
                float m2 = getPixel(data, width, height, col-1, row);
                if(m0 < m1 || m0 < m2)
                {
                    magnitudes[index] = 0;
                }
            }
        }

    看代码可以发现,根据x、y处的角度值,进入不同的if条件,然后找对应的两个点,其实就是根据角度值在3*3中找比较的点,如果两个点中有一个大于当前点,当前点肯定就不是边缘点。

      5.      双阈值边缘连接处理

    双阈值选择与边缘连接方法通过假设两个阈值

    其中一个为高阈值TH另外一个为低阈值TL则有

    a.      对于任意边缘像素低于TL的则丢弃

    b.      对于任意边缘像素高于TH的则保留

    c.      对于任意边缘像素值在TL与TH之间的,如果能通过边缘连接到一个像素大于TH而且边缘所有像素大于最小阈值TL的则保留,否则丢弃


     6.      二值化图像输出结果

    其实第4步就是通过角度去掉一些点,第5步通过幅值去掉一些点

    http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/canny_detector/canny_detector.html?highlight=canny

    https://blog.csdn.net/tigerda/article/details/61192943

    https://blog.csdn.net/jia20003/article/details/41173767

    https://zhuanlan.zhihu.com/p/64350303

  • 相关阅读:
    关于httpd服务的安装、配置
    时间同步ntp服务的安装与配置(作为客户端的配置
    通过挂载系统光盘搭建本地yum仓库的方法
    linux系统的初化始配置(包括网络,主机名,关闭firewalld与selinux)
    Linux下GNOME桌面的安装
    Java面试题汇总
    无敌存储过程分页使用
    正则表达式
    函数
    杂货
  • 原文地址:https://www.cnblogs.com/ymjyqsx/p/9527339.html
Copyright © 2020-2023  润新知