opencv canny边缘检测算法详解

目录
  • 一、边缘检测原理
  • 二、canny算法原理
  • 三、opencv函数支持Canny()
  • 四、代码示例:

一、边缘检测原理

图像的边缘由图像中两个相邻的区域之间的像素集合组成,是指图像中一个区域的结束和另外一个区域的开始。也可以这么理解,图像边缘就是图像中灰度值发生空间突变的像素的集合。梯度方向和幅度是图像边缘的两个性质,沿着跟边缘垂直的的方向,像素值的变化幅度比较平缓;而沿着与边缘平行的方向,则像素值变化幅度变化比较大。于是,根据该变化特性,通常会采用计算一阶或者二阶导数的方法来描述和检测图像边缘。

基于边缘检测的图像分割方法的基本思路是首先检测出图像中的边缘像素,然后再把这些边缘像素集合连结在一起便组成所要的目标区域边界。图像中的边缘可以通过对灰度值求导来检测确定,然而求导数可以通过计算微分算子来实现。在数字图像处理领域,微分运算通常被差分计算所近似代替。

二、 canny算法原理

在1986年,Canny边缘检测算子首次在论文《A Computational Approach to Edge Detection》中提出,目前,Canny边缘检测算子已广泛应用于各种图像处理视觉系统。由于它是从不同视觉对象中提取有用的结构信息,所以了要处理的数据量大大减少。JOHN CANNY总结出,不同视觉系统对边缘检测具有较为类似的要求,所以,发现可以采用一种应用意义广泛的边缘检测技术。
JOHN CANNY采用了如下步骤设计实现了canny算子。

(1)消除噪声。边缘检测的算法的主要思想采用了图像强度的一阶和二阶微分运算,但因为导数对噪声很敏感,所以再求导之前,先对图像源的数据进行平滑预处理再运用边缘检测算法。一般采用滤波器来改善图像的性噪比。所以Canny算子前,先通过高斯模板对原始数据进行卷积操作来抑制图像的噪声,再进行边缘检测。

(2)sobel梯度计算:平滑处理完,canny算子利用已有的一阶导数sobel微分算子来计算梯度,

Gx表示水平方向X的掩码模板,Gy表示垂直方向Y的掩码模板,采用这两个模板与图像进行卷积操作可得到图像边缘的梯度幅值和方向分别如式(4)和(5)所示:

梯度方向被归为垂直,水平,和两个对角线四类,其方向一般总是垂直于边界。

(3)对梯度幅值进行非极大值抑制。意思是遍历整个图像,将某个像素的灰度值与其梯度方向上前后两个像素的灰度值相比,判断其是否最大,如果不是那么这个像素值置为0,即不是边缘;如下图5. 1所示 ,每一列箭头的方向代表步骤二所检测出的(梯度方向与边缘垂直),数值表示对应的梯度方向的幅值。经过非极大值抑制处理之后,第一列所表示梯度方向的幅值2、4、3被置为0,第二列的所表示梯度方向的幅值3、5、4被置为0,以此类推,最终白色边框里的幅值5、6、7、6、7被当作疑似边缘像素点。

(4)使用双阈值算法检测和连接边缘。在上一个步骤得到了存在伪边缘的边缘集,因为通过单阈值处理选取边缘的操作比较难, 所以在Canny算法采用滞后阈值法减少伪边缘数量。如下图5. 1所示:Canny使用了滞后阈值,滞后阈值需要高阈值和低阈值,在进行边缘确定时依据下面的步骤第一,如果某一像素位置的幅值超过高阈值,该像素被保留为边缘像素:第二,如果某一像素位置的幅值小于低阈值,该像素被排除;第三,如果某一像素位置的幅值在两个阈值之间,该像素仅仅在连接到一个高于高阈值的像素时被保留。Canny算法的双阈值中, 大部分噪声被高阈值检测出去除了,但是也损失了有用的边缘信息, 较多的边缘信息则被低阈值检测得到的图像保留着,可取的高与低阈值比在2:1到3:1之间。

图5. 1非极大值抑制示意图图

图5. 2双阈值算法检测示意图

三、opencv 函数支持Canny()

函数原型:

CV_EXPORTS_W void Canny( InputArray image, OutputArray edges,
                         double threshold1, double threshold2,
                         int apertureSize = 3, bool L2gradient = false );

参数说明:

  • image:8位输入图像。
  • edges:输出边缘;单通道8位图像,与图像大小相同。
  • threshold1:迟滞过程的第一个阈值。
  • threshold2:迟滞过程的第二个阈值。
  • apertureSize : Sobel算子的孔径大小。
  • L2gradient:一个标志,指示是否应用更精确的方式计算图像梯度幅值.。

四、代码示例:

    cv::Mat src;
    src = cv::imread("D:\\QtProject\\Opencv_Example\\canny\\canny.jpg", cv::IMREAD_GRAYSCALE);
    if (src.empty()) {
        cout << "matTemplate Cannot load image" << endl;
        return;
    }
    cv::imshow("src", src);

    cv::Mat matCanny;
    const int lowThreshold = 10;
    const int maxThreshold = 200;
    const int kernel_size = 3;
    cv::Canny(src, matCanny, lowThreshold, maxThreshold, kernel_size);
    cv::imshow("matCanny", matCanny);

程序运行效果:

到此这篇关于opencv canny边缘检测算法详解的文章就介绍到这了,更多相关opencv canny边缘检测算法 内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 使用OpenCV-python3实现滑动条更新图像的Canny边缘检测功能

    import cv2 from matplotlib import pyplot as plt import numpy as np img= cv2.imread('39.jpg')#加载图片 cv2.namedWindow('Canny edge detect')#设置窗口,cv2.WINDOW_NORMAL表示窗口大小可自动调节 cv2.namedWindow('Original Image',cv2.WINDOW_NORMAL) cv2.namedWindow('Canny edgeIm

  • OpenCV中Canny边缘检测的实现

    目录 1. Canny 边缘检测理论 1.1.高斯滤波 1.2.Sobel算子计算梯度和方向 1.3.非极大值抑制(定位准确的边缘同时可缩小边缘线宽) 1.4.双阈值检测 2. OpenCV 之 Canny 边缘检测 边缘检测一般是识别目标图像中亮度变化明显的像素点. 因为显著变化的像素点通常反映了图像变化比较重要的地方. 1. Canny 边缘检测理论 Canny 是一种常用的边缘检测算法. 其是在 1986 年 John F.Canny 提出的. Canny 是一种 multi-stage

  • Python实现Opencv cv2.Canny()边缘检测

    目录 1. 效果图 2. 源码 补充:OpenCV-Python 中 Canny() 参数 这篇博客将介绍Canny边缘检测的概念,并利用cv2.Canny()实现边缘检测: Canny边缘检测是一种流行的边缘检测算法.它是由约翰F开发的,是一个多阶段的算法: Canny边缘检测大致包含4个步骤: 降噪(使用高斯滤波去除高频噪声): 计算边缘梯度和方向(SobelX.SobleY核在水平方向和垂直方向对平滑后的图像进行滤波,找到每个像素的边缘梯度和方向): 非最大抑制(在得到梯度大小和方向后,对

  • opencv canny边缘检测算法详解

    目录 一.边缘检测原理 二.canny算法原理 三.opencv函数支持Canny() 四.代码示例: 一.边缘检测原理 图像的边缘由图像中两个相邻的区域之间的像素集合组成,是指图像中一个区域的结束和另外一个区域的开始.也可以这么理解,图像边缘就是图像中灰度值发生空间突变的像素的集合.梯度方向和幅度是图像边缘的两个性质,沿着跟边缘垂直的的方向,像素值的变化幅度比较平缓:而沿着与边缘平行的方向,则像素值变化幅度变化比较大.于是,根据该变化特性,通常会采用计算一阶或者二阶导数的方法来描述和检测图像边

  • Python OpenCV Canny边缘检测算法的原理实现详解

    目录 Gaussian smoothing Computing the gradient magnitude and orientation Non-maxima suppression Hysteresis thresholding OpenCV实现 Gaussian smoothing 总的来说,Canny边缘检测可以分为四个步骤: 由于边缘检测对噪声敏感,因此对图像应用高斯平滑以帮助减少噪声.具体做法是,采用一个5*5的高斯平滑滤波器对图像进行滤波处理. Computing the gra

  • Python图像锐化与边缘检测之Scharr,Canny,LOG算子详解

    目录 一.Scharr算子 二.Cann算子 三.LOG算子 四.总结 一.Scharr算子 由于Sobel算子在计算相对较小的核的时候,其近似计算导数的精度比较低,比如一个3×3的Sobel算子,当梯度角度接近水平或垂直方向时,其不精确性就越发明显.Scharr算子同Sobel算子的速度一样快,但是准确率更高,尤其是计算较小核的情景,所以利用3×3滤波器实现图像边缘提取更推荐使用Scharr算子. Scharr算子又称为Scharr滤波器,也是计算x或y方向上的图像差分,在OpenCV中主要是

  • C++ OpenCV实现图像双三次插值算法详解

    目录 前言 一.图像双三次插值算法原理 二.C++ OpenCV代码 1.计算权重矩阵 2.遍历插值 3. 测试及结果 前言 近期在学习一些传统的图像处理算法,比如传统的图像插值算法等.传统的图像插值算法包括邻近插值法.双线性插值法和双三次插值法,其中邻近插值法和双线性插值法在网上都有很详细的介绍以及用c++编写的代码.但是,网上关于双三次插值法的原理介绍虽然很多,也有对应的代码,但是大多都不是很详细.因此基于自己对原理的理解,自己编写了图像双三次插值算法的c++ opencv代码,在这里记录一

  • OpenCV图像分割之分水岭算法与图像金字塔算法详解

    目录 前言 一.使用分水岭算法分割图像 1.cv2.distanceTransform()函数 2.cv2.connectedComponents()函数 3.cv2.watershed()函数 二.图像金字塔 1.高斯金字塔向下采样 2.高斯金字塔向上采样 3.拉普拉斯金字塔 4.应用图像金字塔实现图像的分割和融合 前言 主要介绍OpenCV中的分水岭算法.图像金字塔对图像进行分割的方法. 一.使用分水岭算法分割图像 分水岭算法的基本原理为:将任意的灰度图像视为地形图表面,其中灰度值高的部分表

  • Python图像处理之边缘检测原理详解

    目录 原理 Sobel检测算子 Laplacian算子 算子比较 原理 边缘检测是图像处理和计算机视觉当中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点,图像的边缘检测可以大幅度的减少数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性,它们绝大多数可以分为两类:基于搜索和基于零穿越. 基于搜索:通过寻找图像一阶导数中max来检测边界,然后利用计算结果估计边缘的局部方向,通常采用梯度的方向,并在此方向找到局部梯度模的最大值,代表的算法是Sobel算子和Scharr算子.

  • python opencv图像处理基本操作示例详解

    目录 1.图像基本操作 ①读取图像 ②显示图像 ③视频读取 ④图像截取 ⑤颜色通道提取及还原 ⑥边界填充 ⑦数值计算 ⑧图像融合 2.阈值与平滑处理 ①设定阈值并对图像处理 ②图像平滑-均值滤波 ③图像平滑-方框滤波 ④图像平滑-高斯滤波 ⑤图像平滑-中值滤波 3.图像的形态学处理 ①腐蚀操作 ②膨胀操作 ③开运算和闭运算 4.图像梯度处理 ①梯度运算 ②礼帽与黑帽 ③图像的梯度处理 5.边缘检测 ①Canny边缘检测 1.图像基本操作 ①读取图像 ②显示图像 该函数中,name是显示窗口的名字

  • Python实现特定场景去除高光算法详解

    目录 算法思路 应用场景 代码实现 实验效果 补充 算法思路 1.求取源图I的平均灰度,并记录rows和cols: 2.按照一定大小,分为N*M个方块,求出每块的平均值,得到子块的亮度矩阵D: 3.用矩阵D的每个元素减去源图的平均灰度,得到子块的亮度差值矩阵E: 4.通过插值算法,将矩阵E差值成与源图一样大小的亮度分布矩阵R: 5.得到矫正后的图像result=I-R: 应用场景 光照不均匀的整体色泽一样的物体,比如工业零件,ocr场景. 代码实现 import cv2 import numpy

  • Python OpenCV机器学习之图像识别详解

    目录 背景 一.人脸识别 二.车牌识别 三.DNN图像分类 背景 OpenCV中也提供了一些机器学习的方法,例如DNN:本篇将简单介绍一下机器学习的一些应用,对比传统和前沿的算法,能从其中看出优劣: 一.人脸识别 主要有以下两种实现方法: 1.哈尔(Haar)级联法:专门解决人脸识别而推出的传统算法: 实现步骤: 创建Haar级联器: 导入图片并将其灰度化: 调用函数接口进行人脸识别: 函数原型: detectMultiScale(img,scaleFactor,minNeighbors) sc

  • Qt+OpenCV实现目标检测详解

    目录 一.创建项目&UI设计 二.代码与演示 演示效果 拓展阅读 一.创建项目&UI设计 创建项目,UI设计如下 文件类型判断 简单的判断文件类型 QString file("sample.jpg"); if (file.contains(".jpg") || file.contains(".bmp") || file.contains(".png")) qDebug()<<"这是图片.&

随机推荐