边缘检测原理 - Sobel, Laplace, Canny算子

栏目: 编程工具 · 发布时间: 5年前

内容简介:Nav logo 数字图像 - 边缘检测原理 - Sobel, Laplace, Canny算子 96 ck2016 2017.02.14 19:14* 字数 1298 阅读 21285评论 3喜欢 37 先来看张图,左边是原图,右边是边缘检测后的图,边缘检测就是检测出图像上的边缘信息,右图用白色的程度表示边缘的深浅。sobel.png 边缘其实就是图像上灰度级变化很快的点的集合。 如何计算出这些变化率很快的点?1.导数,连续函数上某点斜率,导数越大表示变化率越大,变化率越大的地方就越是“边缘”,但是在

Nav logo 数字图像 - 边缘检测原理 - Sobel, Laplace, Canny算子 96 ck2016 2017.02.14 19:14* 字数 1298 阅读 21285评论 3喜欢 37 先来看张图,左边是原图,右边是边缘检测后的图,边缘检测就是检测出图像上的边缘信息,右图用白色的程度表示边缘的深浅。

sobel.png 边缘其实就是图像上灰度级变化很快的点的集合。 如何计算出这些变化率很快的点?

1.导数,连续函数上某点斜率,导数越大表示变化率越大,变化率越大的地方就越是“边缘”,但是在计算机中不常用,因为在斜率90度的地方,导数无穷大,计算机很难表示这些无穷大的东西。

2.微分,连续函数上x变化了dx,导致y变化了dy,dy值越大表示变化的越大,那么计算整幅图像的微分,dy的大小就是边缘的强弱了。 微分与导数的关系:dy = f '(x) dx

举个例子:

在连续函数里叫微分,因为图像是离散的,叫差分,和微分是一个意思,也是求变化率。 差分的定义,f '(x) = f(x + 1) - f(x),用后一项减前一项。 按先后排列 -f(x) + f(x + 1) 提出系数 [-1, 1] 作为滤波模板,跟原图 f(x) 做卷积运算就可以检测边缘了

模板为什么要是奇数的? 因为模板是偶数的话,卷积出来的结果应该是放在中间的,不方便表示。 例如:图像 [10, 20, 30] 跟 [-1, 1] 卷积后的值,应该放在图像 10 跟 20 中间的位置,就是应该放在 0 和 1 号位置的中间,也就是 0.5 号位,但是图像是离散的,中间没得放,只能放在 0 号位,也就是 10 的位置,就偏差了 0.5 的位置,为了方便处理,滤波模板一般都是奇数个的,3,5,7 个的。

Sobel 边缘检测算子 所以用 f '(x) = f(x + 1) - f(x - 1) 近似计算一阶差分。

排好序:[-1 * f(x-1),0 * f(x),1 * f(x+1)] 提出系数:[-1, 0, 1] 所以模板 [-1, 1] 被改造成了 [-1, 0, 1] 二维情况下就是

-1, 0, 1 -1, 0, 1 -1, 0, 1 这个就是 Prewitt 边缘检测算子了。

f(x-1, y-1), f(x, y-1), f(x+1, y-1) f(x-1, y), f(x, y), f(x+1, y) f(x-1, y+1), f(x, y+1), f(x+1, y+1) 中心点 f(x, y) 是重点考虑的,它的权重应该多一些,所以改进成下面这样的

-1, 0, 1 -2, 0, 2 -1, 0, 1 这就是 Sobel 边缘检测算子,偏 x 方向的。(类似二元函数的偏导数,偏x,偏y) 同理可得

-1, -2, -1 0, 0, 0 1, 2, 1 是 sobel 偏 y 方向的算子。

Laplace 边缘检测算子 拉普拉斯是用二阶差分计算边缘的,看连续函数的情况下 在一阶微分图中极大值或极小值处,认为是边缘。 在二阶微分图中极大值和极小值之间的过 0 点,被认为是边缘。

拉普拉斯算子推导: 一阶差分:f '(x) = f(x) - f(x - 1) 二阶差分:f '(x) = (f(x + 1) - f(x)) - (f(x) - f(x - 1)) 化简后:f '(x) = f(x - 1) - 2 f(x)) + f(x + 1) 提取前面的系数:[1, -2, 1]

二维的情况下,同理可得 f '(x, y) = -4 f(x, y) + f(x-1, y) + f(x+1, y) + f(x, y-1) + f(x, y+1) 提取各个系数,写成模板的形式

0, 1, 0 1, -4, 1 0, 1, 0 考虑两个斜对角的情况

1, 1, 1 1, -8, 1 1, 1, 1 这就是拉普拉斯算子,与原图卷积运算即可求出边缘。

Canny 边缘检测算子 canny计算过程 1.高斯滤波器平滑图像。 2.一阶差分偏导计算梯度值和方向。 3.对梯度值不是极大值的地方进行抑制。 4.用双阈值连接图上的联通点。

通俗说一下, 1.用高斯滤波主要是去掉图像上的噪声。 2.计算一阶差分,OpenCV 源码中也是用 sobel 算子来算的。 3.算出来的梯度值,把不是极值的点,全部置0,去掉了大部分弱的边缘。所以图像边缘会变细。 4.双阈值 t1, t2, 是这样的,t1 <= t2 大于 t2 的点肯定是边缘 小于 t1 的点肯定不是边缘 在 t1, t2 之间的点,通过已确定的边缘点,发起8领域方向的搜索(广搜),图中可达的是边缘,不可达的点不是边缘。 最后得出 canny 边缘图。

三个算子区别 sobel 产生的边缘有强弱,抗噪性好 laplace 对边缘敏感,可能有些是噪声的边缘,也被算进来了 canny 产生的边缘很细,可能就一个像素那么细,没有强弱之分。

下面三张图分别是 sobel,canny,laplace 结果图。

sobel算子 canny算子 laplace算子

函数语法介绍:

Laplace算子的函数原型:

dst = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])

src -- 原图像 ddepth -- 图像的深度, -1 表示采用的是与原图像相同的深度。目标图像的深度必须大于等于原图像的深度

【可选参数】

dst -- 目标图像

ksize -- 算子的大小,必须为1、3、5、7。默认为1

scale -- 是缩放导数的比例常数,默认情况下没有伸缩系数

delta -- 是一个可选的增量,将会加到最终的dst中,同样,默认情况下没有额外的值加到dst中

borderType -- 是判断图像边界的模式。这个参数默认值为cv2.BORDER_DEFAULT。。

使用示例:

import cv2

import numpy as np

img = cv2.imread("3.jpg", 0)

gray_lap = cv2.Laplacian(img,cv2.CV_16S,ksize = 3)

dst = cv2.convertScaleAbs(gray_lap)

cv2.imshow('laplacian',dst)

cv2.waitKey(0)

cv2.destroyAllWindows()

原文链接https://www.jianshu.com/p/2334bee37de5


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

深入浅出Rust

深入浅出Rust

范长春 / 机械工业出版社 / 2018-8-21 / 89.00元

本书详细描述了Rust语言的基本语法,穿插讲解一部分高级使用技巧,并以更容易理解的方式解释其背后的设计思想。全书总共分五个部分。 第一部分介绍Rust基本语法,因为对任何程序设计语言来说,语法都是基础,学习这部分是理解其他部分的前提。 第二部分介绍属于Rust独一无二的内存管理方式。它设计了一组全新的机制,既保证了安全性,又保持了强大的内存布局控制力,而且没有额外性能损失。这部分是本书......一起来看看 《深入浅出Rust》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具