OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、边缘检测
    • 1.Canny算子
    • 2.Sobel算子
    • 3.Laplacian算子
    • 4.Scharr滤波器
  • 二、霍夫变换
    • 1.霍夫线变换
    • 2.霍夫圆变换
  • 总结


前言

笔者本科时候有幸接触了OpenCV3.2.0版本的学习,后因考研压力不得不暂时停下学习的脚步,现在考研任务结束了,未来的导师也是从事的该方向,笔者又开始了新一轮的学习。回来发现OpenCV已经出到了4.5.5版本,遂重新下载新版本并决定记录这一学习历程。由于笔者水平有限,可能有错误之处还请诸位大佬多多包涵并烦请指出,让我们一起学习,共同进步。
首先需要说明的是:我是按着毛星云前辈编写的OpenCV3编程入门进行学习的,我会尽力把星云前辈的程序转成符合OpenCV4.5.5版本的。毛星云前辈于2021年12月11日不幸过世,他是我非常敬仰的一位业内大佬,我也是看他的书才开始接触OpenCV。


提示:以下是本篇文章正文内容,下面案例可供参考

一、边缘检测

1.Canny算子

Canny算子由 John F. Canny 在 1986 年开发。Canny 算法也被许多人称为最佳检测器,旨在满足三个主要标准:

  1. 低错误率:意味着对仅存在的边缘的良好检测。
  2. 良好的定位:必须最小化检测到的边缘像素和真实边缘像素之间的距离。
  3. 最小响应:每个边缘只有一个检测器响应。

步骤:

  1. 消除噪声
    过滤掉任何噪音。可使用高斯滤波器。size = 5的高斯核的示例如下所示:OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第1张图片

  2. 计算梯度幅值和方向
    此处按照Sobel滤波器的步骤来操作:
    OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第2张图片
    OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第3张图片

  3. 非极大值抑制
    这会删除不被视为边缘一部分的像素。因此,只保留细线(候选边缘)。

  4. 滞后阈值
    最后一步。Canny 确实使用了两个阈值(上限和下限):
    如果像素梯度高于上限阈值,则该像素被接受为边缘
    如果像素梯度值低于下阈值,则将其拒绝。
    如果像素梯度在两个阈值之间,那么只有当它连接到高于上限阈值的像素时才会被接受。

我们常用的是Canny()函数
在OpenCV官方文档中是这么写的:
void cv::Canny (
InputArray image,
OutputArray edges,
double threshold1,
double threshold2,
int apertureSize = 3,
bool L2gradient = false
)
第一个参数是输入图像,
第二个参数是输出边缘图;单通道 8 位图像,其大小与 image 相同,
第三个参数是滞后过程的第一个阈值,
第四个参数是滞后过程的第二个阈值,
第五个参数是Sobel算子的孔径大小,
第六个参数是计算图像梯度幅值的标识


2.Sobel算子

Sobel算子结合了高斯平滑和微分求导两个部分,用来计算图像灰度函数的近似梯度。因此结果或多或少能抵抗噪声。大多数情况下,使用 (xorder = 1, yorder = 0, ksize = 3) 或 (xorder = 0, yorder = 1, ksize = 3) 调用该函数来计算第一个 x 或 y 图像导数。
第一种情况(计算x)对应于一个内核:
OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第4张图片
第二种情况(计算y)对应于第二个内核:
OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第5张图片
我们常用的是Sobel()函数
在OpenCV官方文档中是这么写的:
void cv::Sobel (
InputArray src,
OutputArray dst,
int ddepth,
int dx,
int dy,
int ksize = 3,
double scale = 1,
double delta = 0,
int borderType = BORDER_DEFAULT
)
第一个参数是输入图像,
第二个参数是输出与 src 大小和通道数相同的图像,
第三个参数是导数 x 的阶数,
第四个参数是导数 y 的阶数,
第五个参数是扩展 Sobel 核的大小;它必须是 1、3、5 或 7,
第六个参数是计算导数值的可选比例因子;默认情况下,不应用缩放,
第七个参数是在将结果存储到 dst 之前添加到结果中的可选增量值,
第八个参数是像素外推法


3.Laplacian算子

函数通过将使用 Sobel 算子计算的第二个 x 和 y 导数相加来计算源图像的拉普拉斯算子:
在这里插入图片描述

这是在ksize > 1. 当 时ksize == 1,拉普拉斯算子是通过使用以下方法过滤图像来计算的3 × 3阵:
OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第6张图片
我们常用的是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 之前添加到结果的可选增量值,
第七个参数是像素外推法


4.Scharr滤波器

使用 Scharr 算子计算第一个 x 或 y 图像导数。该函数使用 Scharr算子计算第一个 x 或 y 空间图像导数:
在这里插入图片描述
我们常用的是Scharr()函数
在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 大小和通道数相同的图像,
第三个参数是目标图像的所需深度,
第四个参数是导数 x 的阶数,
第五个参数是导数 y 的阶数,
第六个参数是计算导数值的可选比例因子;默认情况下,不应用缩放,
第七个参数是在将结果存储到 dst 之前添加到结果中的可选增量值,
第八个参数是像素外推法


二、霍夫变换

1.霍夫线变换

霍夫线变换是一种用于检测直线的变换。为了应用变换,首先需要进行边缘检测预处理。(这段星云前辈的书中讲的非常好,很容易懂)
原理:在笛卡尔坐标系中:可由参数斜率和截距(m,b)表示
在极坐标系:可由参数极径和极角(r,θ)表示
OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第7张图片
对于霍夫变换,可采用第二种方式极坐标系来表示直线:
在这里插入图片描述
化简得:
在这里插入图片描述
如果对于给定的(X0,y0)我们绘制穿过它的直线,我们会得到一个正弦曲线
OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第8张图片
如果两个不同点的曲线在平面上相交,这意味着他们将通过同一条直线
OpenCV4.5.5学习笔记(十三):边缘检测(Canny算子,Sobel算子,Laplacian算子以及Scharr滤波器)和霍夫变换(线与圆)_第9张图片
我们常用的是HoughLines()函数
在OpenCV官方文档中是这么写的:
void cv::HoughLines (
InputArray image,
OutputArray lines,
double rho,
double theta,
int threshold,
double srn = 0,
double stn = 0,
double min_theta = 0,
double max_theta = CV_PI
)
第一个参数是输入图像,
第二个参数是线的输出向量,
第三个参数是累加器的距离分辨率,
第四个参数是累加器的角度分辨率,
第五个参数是累加器阈值参数,
第六个参数是对于多尺度霍夫变换,它是距离分辨率 rho 的除数,
第七个参数是对于多尺度霍夫变换,它是距离分辨率 theta 的一个除数,
第八个参数是对于标准和多尺度霍夫变换,检查线的最小角度,
第九个参数是对于标准和多尺度霍夫变换,检查线的最大角度

2.霍夫圆变换

霍夫圆变换的工作方式与前面教程中解释的霍夫线变换大致相似。
在线检测案例中,一条线由两个参数定义。在圆形的情况下,我们需要三个参数来定义一个圆形:( x,y,r )
为了提高效率,OpenCV 实现了一种比标准霍夫变换稍微复杂的检测方法:霍夫梯度法,它由两个主要阶段组成。第一阶段涉及边缘检测并找到可能的圆心,第二阶段为每个候选中心找到最佳半径
我们常用的是HoughCircles ()函数
在OpenCV官方文档中是这么写的:
void cv::HoughCircles (
InputArray image,
OutputArray circles,
int method,
double dp,
double minDist,
double param1 = 100,
double param2 = 100,
int minRadius = 0,
int maxRadius = 0
)
第一个参数是输入图像,
第二个参数是找到的圆的输出向量,
第三个参数是检测方法,
第四个参数是累加器分辨率与图像分辨率的反比,
第五个参数是检测到的圆的中心之间的最小距离,
第六个参数是第一个特定于方法的参数,
第七个参数是第二个方法特定的参数,
第八个参数是最小圆半径,
第九个参数是最大圆半径


总结

今天主要学习了边缘检测和直线与圆的检测,星云前辈的《OpenCV3》关于这一部分讲的特别好,非常通俗易懂。

你可能感兴趣的:(OpenCV,opencv,windows,c++,visual,studio)