【OpenCV】OpenCV基础教程(7)—— 边缘检测

7. 边缘检测

7.1 Roberts算子

Roberts边缘矩阵是图像矩阵与以下两个卷积核分别做卷积:
R o b e r t s 135 = [ 1 0 0 − 1 ] , R o b e r t s 45 = [ 0 1 − 1 0 ] \mathbf{Robert}{{\mathbf{s}}_{135}}=\left[ \begin{matrix}1 & 0 \\0 & -1 \\\end{matrix} \right],\mathbf{Robert}{{\mathbf{s}}_{45}}=\left[ \begin{matrix}0 & 1 \\-1 & 0 \\\end{matrix} \right] Roberts135=[1001],Roberts45=[0110]

  • R o b e r t s 135 \mathbf{Robert}{{\mathbf{s}}_{135}} Roberts135锚点的位置在卷积核逆时针翻转180°后的第0行第0列;
  • R o b e r t s 45 \mathbf{Robert}{{\mathbf{s}}_{45}} Roberts45锚点的位置在卷积核逆时针翻转180°后的第0行第1列。

与Roberts核做卷积,本质上是两个对角方向上的差分。

  • R o b e r t s 45 \mathbf{Robert}{{\mathbf{s}}_{45}} Roberts45卷积后的结果取绝对值,反映的是45°方向上的灰度变化率;
  • R o b e r t s 135 \mathbf{Robert}{{\mathbf{s}}_{135}} Roberts135卷积后的结果取绝对值,反映的是135°方向上的灰度变化率;

可以对Roberts算子进行改进:
R o b e r t s x = [ 1 − 1 ] , R o b e r t s y = [ 1 − 1 ] \mathbf{Robert}{{\mathbf{s}}_{x}}=\left[ \begin{matrix} 1 & -1 \\ \end{matrix} \right],\mathbf{Robert}{{\mathbf{s}}_{y}}=\left[ \begin{matrix} 1 \\ -1 \\ \end{matrix} \right] Robertsx=[11],Robertsy=[11]

  • R o b e r t s x \mathbf{Robert}{{\mathbf{s}}_{x}} Robertsx锚点的位置在卷积核逆时针翻转180°后的第0行第0列;
  • R o b e r t s y \mathbf{Robert}{{\mathbf{s}}_{y}} Robertsy锚点的位置在卷积核逆时针翻转180°后的第0行第0列。

与Roberts核做卷积,本质上是两个对角方向上的差分。

  • R o b e r t s x \mathbf{Robert}{{\mathbf{s}}_{x}} Robertsx卷积后的结果取绝对值,反映的是水平方向上的灰度变化率;
  • R o b e r t s y \mathbf{Robert}{{\mathbf{s}}_{y}} Robertsy卷积后的结果取绝对值,反映的是垂直方向上的灰度变化率;

在使用由两个或者多个卷积核组成的边缘检测算子时,假设有 𝑛 个卷积核,记 c o v 1 , c o v 2 , ⋯   , c o v n \mathbf{co}{{\mathbf{v}}_{1}},\mathbf{co}{{\mathbf{v}}_{2}},\cdots ,\mathbf{co}{{\mathbf{v}}_{n}} cov1,cov2,,covn为图像分别与各卷积核做卷积后的结果,通常有四种方式来衡量最后输出的边缘强度:

  1. 取对应位置绝对值的和;
  2. 取对应位置平方和的开方;
  3. 取对应位置绝对值的最大值;
  4. 插值法: ∑ i = 1 n a i ∣ c o v i ∣ \sum\limits_{i=1}^{n}{{{a}_{i}}\left| \mathbf{co}{{\mathbf{v}}_{i}} \right|} i=1naicovi,其中 a i ≥ 0 , ∑ i = 1 n a i = 1 {{a}_{i}}\ge 0,\sum\limits_{i=1}^{n}{{{a}_{i}}=1} ai0,i=1nai=1

其中取绝对值的最大值的方式,对边缘的走向有些敏感,而其他几种方式可以获得性能更一致的全方位响应。

取平方和的开方的方式效果一般是最好的,但是同时会更加耗时。


Roberts 边缘检测因为使用了很少的邻域像素来近似边缘强度,因此对图像中的噪声具有高度敏感性。

可以先对图像进行平滑处理,然后进行Roberts边缘检测。

7.2 Prewitt边缘检测

标准的Prewitt边缘检测算子由以下两个卷积核组成:
p r e w i t t x = [ 1 0 − 1 1 0 − 1 1 0 − 1 ] , p r e w i t t y = [ 1 1 1 0 0 0 − 1 − 1 − 1 ] \mathbf{prewit}{{\mathbf{t}}_{x}}=\left[ \begin{matrix} 1 & 0 & -1 \\ 1 & 0 & -1 \\ 1 & 0 & -1 \\ \end{matrix} \right],\mathbf{prewit}{{\mathbf{t}}_{y}}=\left[ \begin{matrix} 1 & 1 & 1 \\ 0 & 0 & 0 \\ -1 & -1 & -1 \\ \end{matrix} \right] prewittx=111000111,prewitty=101101101

  • 图像与 p r e w i t t x \mathbf{prewit}{{\mathbf{t}}_{x}} prewittx卷积后可以反映图像垂直方向上的边缘;
  • 图像与 p r e w i t t y \mathbf{prewit}{{\mathbf{t}}_{y}} prewitty卷积后可以反映图像水平方向上的边缘。

这两个卷积核是可分离的。分离的结果如下:
p r e w i t t x = [ 1 1 1 ] ★ [ 1 0 − 1 ] , p r e w i t t y = [ 1 1 1 ] ★ [ 1 0 − 1 ] \mathbf{prewit}{{\mathbf{t}}_{x}}=\left[ \begin{matrix} 1 \\ 1 \\ 1 \\ \end{matrix} \right]\bigstar \left[ \begin{matrix} 1 & 0 & -1 \\ \end{matrix} \right],\mathbf{prewit}{{\mathbf{t}}_{y}}=\left[ \begin{matrix} 1 & 1 & 1 \\ \end{matrix} \right]\bigstar \left[ \begin{matrix} 1 \\ 0 \\ -1 \\ \end{matrix} \right] prewittx=111[101],prewitty=[111]101
从分离的结果来看:

  • p r e w i t t x \mathbf{prewit}{{\mathbf{t}}_{x}} prewittx算子实际上先对图像进行垂直方向上的非归一化的均值平滑,然后进行水平方向上的差分;
  • p r e w i t t y \mathbf{prewit}{{\mathbf{t}}_{y}} prewitty算子实际上先对图像进行水平方向上的非归一化的均值平滑,然后进行垂直方向上的差分。

由于对图像进行了平滑处理(同一方向相邻三个梯度的加权平均),所以对噪声较多的图像进行Prewitt边缘检测得到的边缘比Roberts要好。


可以对标准的Prewitt算子进行改进:
p r e w i t t 135 = [ 1 1 0 1 0 − 1 0 − 1 − 1 ] , p r e w i t t 45 = [ 0 1 1 − 1 0 1 − 1 − 1 0 ] \mathbf{prewit}{{\mathbf{t}}_{135}}=\left[ \begin{matrix} 1 & 1 & 0 \\ 1 & 0 & -1 \\ 0 & -1 & -1 \\ \end{matrix} \right],\mathbf{prewit}{{\mathbf{t}}_{45}}=\left[ \begin{matrix} 0 & 1 & 1 \\ -1 & 0 & 1 \\ -1 & -1 & 0 \\ \end{matrix} \right] prewitt135=110101011,prewitt45=011101110
以上算子可以反映45°和135°方向上的边缘。但是,这两个卷积核是不可分离的。

7.3 Sobel边缘检测

7.3.1 三阶的Sobel算子

在图像的平滑处理中,高斯平滑的效果往往比均值平滑要好,因此把 Prewitt 算子的非归一化的均值卷积核替换成非归一化的高斯卷积核,就可以构建 3 阶的 Sobel 边缘检测算子。
KaTeX parse error: No such environment: align at position 8: \begin{̲a̲l̲i̲g̲n̲}̲ & \mathbf{so…

7.3.2 高阶的Sobel算子
窗口大小平滑算子(二项式展开式的系数)差分算子
21 11 -1
31 2 11 0 -1
41 3 3 11 1 -1 -1
51 4 6 4 11 2 0 -2 -1

OpenCV函数如下:

void cv::Sobel(cv::InputArray src, cv::OutputArray dst, int ddepth, int dx, int dy, int ksize = 3, double scale = (1.0), double delta = (0.0), int borderType = 4)

src:输入矩阵

dst:输出矩阵,即 src 与 Sobel 核的卷积

ddepth:输出矩阵的数据类型

dx:当 dx ≠ 0 时,src 与差分方向为水平方向上的 Sobel 核卷积

dy:当 dx = 0, dy ≠ 0 时,src 与差分方向为垂直方向上的 Sobel 核卷积

ksize:sobel 核的尺寸,值为 1,3,5,7

scale:比例系数

delta:平移系数

borderType:边界扩充类型

7.4 Scharr算子

s c h a r r x = [ 3 0 − 3 10 0 − 10 3 0 − 3 ] , s c h a r r y = [ 3 10 3 0 0 0 − 3 − 10 − 3 ] \mathbf{scharr}_{x}=\left[ \begin{matrix} 3 & 0 & -3 \\ 10 & 0 & -10 \\ 3 & 0 & -3 \\ \end{matrix} \right],\mathbf{scharr}_{y}=\left[ \begin{matrix} 3 & 10 & 3 \\ 0 & 0 & 0 \\ -3 & -10 & -3 \\ \end{matrix} \right] scharrx=31030003103,scharry=30310010303

这两个卷积核是不可分离的。同样地,Scharr边缘检测算子也可以扩展到其他方向,比如:
s c h a r r 135 = [ 10 3 0 3 0 − 3 0 − 3 − 10 ] , s c h a r r 45 = [ 0 3 10 − 3 0 3 − 10 − 3 0 ] \mathbf{scharr}_{135}=\left[ \begin{matrix} 10 & 3 & 0 \\ 3 & 0 & -3 \\ 0 & -3 & -10 \\ \end{matrix} \right],\mathbf{scharr}_{45}=\left[ \begin{matrix} 0 & 3 & 10 \\ -3 & 0 & 3 \\ -10 & -3 & 0 \\ \end{matrix} \right] scharr135=10303030310,scharr45=03103031030
OpenCV函数如下:

void cv::Scharr(InputArray src, OutputArray dst, int ddepth, int dx, int dy, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT)

src:输入矩阵

dst:输出矩阵,即 src 与 Scharr 核的卷积

ddepth:输出矩阵的数据类型

dx:当 dx ≠ 0 时,src 与差分方向为水平方向上的 Scharr 核卷积

dy:当 dx = 0, dy ≠ 0 时,src 与差分方向为垂直方向上的 Scharr 核卷积

ksize:Scharr 核的尺寸,值为 1,3,5,7

scale:比例系数(默认即可)

delta:平移系数(默认即可)

borderType:边界扩充类型

7.5 Kirsch算子

上面所介绍的边缘检测算子均是由两个方向上的卷积核组成的,接下来介绍两种由各个方向上的卷积核组成的边缘检测算子(Kirsch算子和Robinson算子)。

Kirsch算子由以下8个卷积核组成:
k 1 = [ 5 5 5 − 3 0 − 3 − 3 − 3 − 3 ] , k 2 = [ − 3 − 3 − 3 − 3 0 − 3 5 5 5 ] , k 3 = [ − 3 5 5 − 3 0 5 − 3 − 3 − 3 ] , k 4 = [ − 3 − 3 − 3 5 0 − 3 5 5 − 3 ] k 5 = [ − 3 − 3 5 − 3 0 5 − 3 − 3 5 ] , k 6 = [ 5 − 3 − 3 5 0 − 3 5 − 3 − 3 ] , k 7 = [ − 3 − 3 − 3 − 3 0 5 − 3 5 5 ] , k 8 = [ 5 5 − 3 5 0 − 3 − 3 − 3 − 3 ] \begin{matrix} {{k}_{1}}=\left[ \begin{matrix} 5 & 5 & 5 \\ -3 & 0 & -3 \\ -3 & -3 & -3 \\ \end{matrix} \right],{{k}_{2}}=\left[ \begin{matrix} -3 & -3 & -3 \\ -3 & 0 & -3 \\ 5 & 5 & 5 \\ \end{matrix} \right],{{k}_{3}}=\left[ \begin{matrix} -3 & 5 & 5 \\ -3 & 0 & 5 \\ -3 & -3 & -3 \\ \end{matrix} \right],{{k}_{4}}=\left[ \begin{matrix} -3 & -3 & -3 \\ 5 & 0 & -3 \\ 5 & 5 & -3 \\ \end{matrix} \right] \\ {{k}_{5}}=\left[ \begin{matrix} -3 & -3 & 5 \\ -3 & 0 & 5 \\ -3 & -3 & 5 \\ \end{matrix} \right],{{k}_{6}}=\left[ \begin{matrix} 5 & -3 & -3 \\ 5 & 0 & -3 \\ 5 & -3 & -3 \\ \end{matrix} \right],{{k}_{7}}=\left[ \begin{matrix} -3 & -3 & -3 \\ -3 & 0 & 5 \\ -3 & 5 & 5 \\ \end{matrix} \right],{{k}_{8}}=\left[ \begin{matrix} 5 & 5 & -3 \\ 5 & 0 & -3 \\ -3 & -3 & -3 \\ \end{matrix} \right] \\ \end{matrix} k1=533503533,k2=335305335,k3=333503553,k4=355305333k5=333303555,k6=555303333,k7=333305355,k8=553503333
图像与每一个核进行卷积,然后取绝对值作为对应方向上的边缘强度的量化。对 8 个卷积结果取绝对值,然后在对应值位置取最大值作为最后输出的边缘强度。在进行边缘强度的灰度级显示时,将大于 255 的值截断为 255 即可

7.6 Robinson算子

与Kirsch算子类似,Robinson算子也是由以下8个卷积核组成:
r 1 = [ 1 1 1 1 − 2 1 − 1 − 1 − 1 ] , r 2 = [ 1 1 1 − 1 − 2 1 − 1 − 1 1 ] , r 3 = [ − 1 1 1 − 1 − 2 1 − 1 1 1 ] , r 4 = [ − 1 − 1 1 − 1 − 2 1 1 1 1 ] r 5 = [ − 1 − 1 − 1 1 − 2 1 1 1 1 ] , r 6 = [ 1 − 1 − 1 1 − 2 − 1 1 1 1 ] , r 7 = [ 1 1 − 1 1 − 2 − 1 1 1 − 1 ] , r 8 = [ 1 1 1 1 − 2 − 1 1 − 1 − 1 ] \begin{matrix} {{r}_{1}}=\left[ \begin{matrix} 1 & 1 & 1 \\ 1 & -2 & 1 \\ -1 & -1 & -1 \\ \end{matrix} \right],{{r}_{2}}=\left[ \begin{matrix} 1 & 1 & 1 \\ -1 & -2 & 1 \\ -1 & -1 & 1 \\ \end{matrix} \right],{{r}_{3}}=\left[ \begin{matrix} -1 & 1 & 1 \\ -1 & -2 & 1 \\ -1 & 1 & 1 \\ \end{matrix} \right],{{r}_{4}}=\left[ \begin{matrix} -1 & -1 & 1 \\ -1 & -2 & 1 \\ 1 & 1 & 1 \\ \end{matrix} \right] \\ {{r}_{5}}=\left[ \begin{matrix} -1 & -1 & -1 \\ 1 & -2 & 1 \\ 1 & 1 & 1 \\ \end{matrix} \right],{{r}_{6}}=\left[ \begin{matrix} 1 & -1 & -1 \\ 1 & -2 & -1 \\ 1 & 1 & 1 \\ \end{matrix} \right],{{r}_{7}}=\left[ \begin{matrix} 1 & 1 & -1 \\ 1 & -2 & -1 \\ 1 & 1 & -1 \\ \end{matrix} \right],{{r}_{8}}=\left[ \begin{matrix} 1 & 1 & 1 \\ 1 & -2 & -1 \\ 1 & -1 & -1 \\ \end{matrix} \right] \\ \end{matrix} r1=111121111,r2=111121111,r3=111121111,r4=111121111r5=111121111,r6=111121111,r7=111121111,r8=111121111
其边缘检测的过程与Kirsch一致。

7.7 Canny边缘检测

基于卷积运算的边缘检测算法,比如 Sobel、Prewitt 等,有如下两个缺点:

  1. 没有充分利用边缘的梯度方向。
  2. 最后输出的边缘二值图,只是简单地利用阈值进行处理,显然如果阈值过大,则会损失很多边缘信息;如果阈值过小,则会有很多噪声。

而 Canny 边缘检测基于这两点做了改进,提出了:

  1. 基于边缘梯度方向的非极大值抑制。
  2. 双阈值的滞后阈值处理。
7.7.1 算法原理

略,具体见书P248。

7.7.2 OpenCV函数
void cv::Canny( InputArray image, OutputArray edges, double threshold1, double threshold2, int apertureSize = 3, bool L2gradient = false );

image:输入图像

edges:输出图像

threshold1:低阈值

threshold2:高阈值

apertureSize:使用的 Sobel 核的窗口大小,默认是 3 × 3,也可以尝试 5 × 5 或 7 × 7 等

L2gradient:计算边缘强度时使用的方式,true 代表使用的是平方和开方的方式,false 代表使用的是绝对值和的方式。

7.8 Laplacian算子

对二维连续函数 f ( x , y ) f(x,y) f(x,y)求梯度如下:
KaTeX parse error: No such environment: align at position 8: \begin{̲a̲l̲i̲g̲n̲}̲ & {{\nabla }…
将其推广到离散的二维数组(矩阵),即矩阵的拉普拉斯变换是矩阵与拉普拉斯核(以下两种表示都可以,只差一个负号)的卷积:
l 0 = [ 0 − 1 0 − 1 4 − 1 0 − 1 0 ] , l 0 − = [ 0 1 0 1 − 4 1 0 1 0 ] {{l}_{0}}=\left[ \begin{matrix} 0 & -1 & 0 \\ -1 & 4 & -1 \\ 0 & -1 & 0 \\ \end{matrix} \right],{{l}_{{{0}^{-}}}}=\left[ \begin{matrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \\ \end{matrix} \right] l0=010141010,l0=010141010
图像矩阵与拉普拉斯核的卷积本质上是计算任意位置的值与其在水平方向垂直方向上四个相邻点平均值之间的差值。

此外,Laplacian算子还有一些常用的形式:
l 1 = [ − 1 − 1 − 1 − 1 8 − 1 − 1 − 1 − 1 ] , l 2 = [ 2 − 1 2 − 1 − 4 − 1 2 − 1 2 ] , l 3 = [ 0 2 0 2 − 8 2 0 2 0 ] , l 4 = [ 2 0 2 0 − 8 0 2 0 2 ] {{l}_{1}}=\left[ \begin{matrix} -1 & -1 & -1 \\ -1 & 8 & -1 \\ -1 & -1 & -1 \\ \end{matrix} \right],{{l}_{2}}=\left[ \begin{matrix} 2 & -1 & 2 \\ -1 & -4 & -1 \\ 2 & -1 & 2 \\ \end{matrix} \right],{{l}_{3}}=\left[ \begin{matrix} 0 & 2 & 0 \\ 2 & -8 & 2 \\ 0 & 2 & 0 \\ \end{matrix} \right],{{l}_{4}}=\left[ \begin{matrix} 2 & 0 & 2 \\ 0 & -8 & 0 \\ 2 & 0 & 2 \\ \end{matrix} \right] l1=111181111,l2=212141212,l3=020282020,l4=202080202
拉普拉斯核内所有值的和必须等于 0,这样就使得在恒等灰度值区域不会产生错误的边缘,而且上述几种形式的拉普拉斯算子均是不可分离的。

  • Laplacian算子的缺点:

    • 没有对图像进行了平滑处理,所以它会对噪声产生较大的响应,误将噪声作为边缘;
    • 无法像Sobel 和 Prewitt 算子那样单独得到水平方向、垂直方向或者其他固定方向上的边缘。
  • Laplacian算子的优点:

    • 拉普拉斯算子的优点是它只有一个卷积核,所以其计算成本比其他算子要低。

OpenCV函数如下:

void cv::Laplacian(InputArray src, OutputArray dst, int ddepth, int ksize = 1, double scale = 1, double delta = 0, int borderType = BORDER_DEFAULT)

src:输入矩阵

dst:输出矩阵

ddepth:输出矩阵的数据类型(位深)

ksize:拉普拉斯核的类型(必须是正奇数)

​ ksize = 1:采用 l 0 − {l}_{{{0}^{-}}} l0形式的拉普拉斯核

​ ksize = 3:采用 l 4 {l}_{4} l4形式的拉普拉斯核

scale:比例系数(默认即可)

delta:平移系数(默认即可)

borderType:边界扩充类型

7.9 高斯拉普拉斯(LoG)边缘检测

背景:Laplacian边缘检测算子没有对图像做平滑处理,会对噪声产生明显的响应。所以在用拉普拉斯核进行边缘检测时,首先要对图像进行高斯平滑处理,然后再与拉普拉斯核进行卷积运算。

这里进行了两次卷积运算。而高斯拉普拉斯边缘检测算法只用进行一次卷积运算。

基本原理就是对二维高斯函数 g a u s s ( x , y , σ ) gauss(x,y,\sigma) gauss(x,y,σ)求梯度(具体略)。

7.10 高斯差分(DoG)边缘检测

7.11 Marr-Hildreth边缘检测

高斯差分和高斯拉普拉斯是 Marr-Hildreth 边缘检测的基底。

对于高斯差分和高斯拉普拉斯边缘检测,最后一步只是简单地进行阈值化处理,显然所得到的边缘很粗略,不够精准。

Marr-Hildreth 边缘检测可以简单地理解为对高斯差分和高斯拉普拉斯检测到的边缘的细化(细节略),就像 Canny 对 Sobel、Prewitt 检测到的边缘的细化一样。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉算法。下面是一个简要的OpenCV计算机视觉基础教程: 1. 安装OpenCV:首先,你需要下载并安装OpenCV库。你可以从OpenCV官方网站上找到适合你操作系统的安装包,并按照官方文档中的指导进行安装。 2. 图像读取和显示:使用OpenCV可以轻松地读取和显示图像。你可以使用`cv2.imread()`函数读取图像文件,并使用`cv2.imshow()`函数显示图像。 3. 图像处理:OpenCV提供了许多图像处理函数,例如调整图像大小、改变图像亮度和对比度、图像平滑、边缘检测等。你可以根据需要选择适当的函数来处理图像。 4. 特征提取:在计算机视觉中,特征提取是一个重要的步骤。OpenCV提供了各种特征提取算法,如Harris角点检测、SIFT、SURF、ORB等。这些算法可以帮助你在图像中找到感兴趣的特征点。 5. 目标检测OpenCV还提供了一些目标检测算法,如Haar级联检测器、HOG+SVM等。这些算法可以用于在图像或视频中检测出特定的目标物体。 6. 图像分割:图像分割是将图像划分为不同的区域或对象的过程。OpenCV提供了一些图像分割算法,如基于阈值的分割、基于边缘的分割、基于区域的分割等。 7. 机器学习与深度学习:OpenCV还集成了一些机器学习和深度学习的功能,如支持向量机(SVM)、神经网络等。你可以使用这些功能来进行图像分类、目标识别等任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Quentin_HIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值