zoukankan      html  css  js  c++  java
  • OpenCV---Canny边缘提取

    一:Canny算法介绍

    Canny 的目标是找到一个最优的边缘检测算法,最优边缘检测的含义是:
    好的检测- 算法能够尽可能多地标识出图像中的实际边缘。
    好的定位- 标识出的边缘要尽可能与实际图像中的实际边缘尽可能接近。
    最小响应- 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

    推文:Canny边缘检测算法原理及其VC实现详解(一)

    1.高斯模糊--GaussianBlur  消除噪声。 一般情况下,使用高斯平滑滤波器卷积降噪。,因为canny是对噪声敏感的算法,所以先降噪,但是降噪不要太过,以免丢失
    2.灰度转换--cvtColor  
    3.计算梯度--Sobel/Scharr
    4.非最大信号抑制
    5.高低阈值输出二值图像

    补充:

    非最大信号抑制

    在Canny算法中,非极大值抑制是进行边缘检测的重要步骤,通俗意义上是指寻找像素点局部最大值,将非极大值点所对应的灰度值置为0
    sobel算子中有一个x,y
    根据x,y可以求出一个θ角度
    1.要进行非极大值抑制,就首先要确定像素点C的灰度值在其8值邻域内是否为最大。是最大则下一步
    2.图中蓝色的线条方向为C点的梯度方向,这样就可以确定其局部的最大值肯定分布在这条线上,也即出了C点外,梯度方向的交点dTmp1和dTmp2这两个点的值也可能会是局部最大值。
    因此,判断C点灰度与这两个点灰度大小即可判断C点是否为其邻域内的局部最大灰度点
    3.如果经过判断,C点灰度值小于这两个点中的任一个,那就说明C点不是局部极大值,那么则可以排除C点为边缘。
    完成非极大值抑制后,会得到一个二值图像,非边缘的点灰度值均为0,可能为边缘的局部灰度极大值点可设置其灰度为128
    根据下文的具体测试图像可以看出,这样一个检测结果还是包含了很多由噪声及其他原因造成的假边缘。因此还需要进一步的处理。

    高低阈值输出二值图像

     二:Canny边缘提取实现

    def edge_demo(image):
        #1.高斯模糊
        blurred = cv.GaussianBlur(image,(3,3),0)
        #2.灰度转换
        gray = cv.cvtColor(blurred,cv.COLOR_RGB2GRAY)
        #3.计算梯度
        xgrad = cv.Sobel(gray,cv.CV_16SC1,1,0)  #canny方法API要求不允许使用浮点数
        ygrad = cv.Sobel(gray,cv.CV_16SC1,0,1)
        #4.Canny方法中包含非最大信号抑制和双阈值输出
        edge_output = cv.Canny(xgrad,ygrad,50,150)  #50是低阈值,150是高阈值
        cv.imshow("Canny Edge",edge_output)
    
        dst = cv.bitwise_and(image,image,mask=edge_output)  #相与,获取颜色
        cv.imshow("Color Edge",dst)

    src = cv.imread("./g.png")  #读取图片
    cv.namedWindow("input image",cv.WINDOW_AUTOSIZE) #创建GUI窗口,形式为自适应
    cv.imshow("input image",src) #通过名字将图像和窗口联系

    edge_demo(src)

    cv.waitKey(0) #等待用户操作,里面等待参数是毫秒,我们填写0,代表是永远,等待用户操作
    cv.destroyAllWindows() #销毁所有窗口

     使用Canny计算梯度

    def edge_demo(image):
        #1.高斯模糊
        blurred = cv.GaussianBlur(image,(3,3),0)
        #2.灰度转换
        gray = cv.cvtColor(blurred,cv.COLOR_RGB2GRAY)
        #3.直接传入灰度图像,Canny方法中包含计算梯度,非最大信号抑制和双阈值输出
        edge_output = cv.Canny(gray,50,150)  #50是低阈值,150是高阈值
        cv.imshow("Canny Edge",edge_output)
    
        dst = cv.bitwise_and(image,image,mask=edge_output)
        cv.imshow("Color Edge",dst)

     相关知识补充

    (一)Canny方法

    (1)需要我们求出梯度

    Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]]) -> edges
    使用带自定义图像渐变的Canny算法在图像中查找边缘,
    
    其函数原型为:Canny(dx, dy, threshold1, threshold2[, edges[, L2gradient]]) -> edges
    
    dx参数表示输入图像的x导数(x导数满足16位,选择CV_16SC1或CV_16SC3)
    
    dy参数表示输入图像的y导数(y导数满足16位,选择CV_16SC1或CV_16SC3)。
    
    threshold1参数表示设置的低阈值。
    
    threshold2参数表示设置的高阈值,一般设定为低阈值的3倍 (根据Canny算法的推荐)。
    
    edges参数表示输出边缘图像,单通道8位图像。
    
    L2gradient参数表示L2gradient参数表示一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开方),否则使用L1范数(直接将两个方向导数的绝对值相加)。

    (2)直接调用Canny算法在单通道灰度图像中查找边缘,

    def Canny(image, threshold1, threshold2, edges=None, apertureSize=None, L2gradient=None): # real signature unknown; restored from __doc__
    image参数表示8位输入图像。
    
    threshold1参数表示设置的低阈值。
    
    threshold2参数表示设置的高阈值,一般设定为低阈值的3倍 (根据Canny算法的推荐)。
    
    edges参数表示输出边缘图像,单通道8位图像。
    
    apertureSize参数表示Sobel算子的大小。
    
    L2gradient参数表示一个布尔值,如果为真,则使用更精确的L2范数进行计算(即两个方向的倒数的平方和再开方),否则使用L1范数(直接将两个方向导数的绝对值相加)。
  • 相关阅读:
    基于Apache+php+mysql的许愿墙网站的搭建
    关于php留言本网站的搭建
    httpd服务的安装、配置
    linux下面桌面的安装
    时间同步ntp服务的安装与配置
    通过挂载系统光盘搭建本地yum仓库的方法
    linux系统root用户忘记密码的重置方法
    linux系统的初化始配置
    Linux下通过PXE服务器安装Linux系统
    Linux设置RSA密钥登录
  • 原文地址:https://www.cnblogs.com/ssyfj/p/9275058.html
Copyright © 2011-2022 走看看