当前位置: 首页 > news >正文

CV:边缘检测的算法包含 Prewitt、Sobel、Laplacian 和 Canny。

目录

1. 边缘检测(Prewitt)

2. 边缘检测(Sobel)

3. 边缘检测(Laplacian)

3. 边缘检测(Canny)


边缘检测的算法包含 Prewitt、Sobel、Laplacian 和 Canny。

人在图像识别上具有难以置信的能力,可以在几毫秒内处理图像,确定图像的边缘、图像内物体的位置和标签。研究者让计算机模拟人检测图像的边缘,是在图像中找到变化明显的区域,也就是像素明显变化的点或区域。

1. 边缘检测(Prewitt)

接下来用黑白像素值介绍如何获得图像的边缘,先建立一个全为 0 的三维数组,维度分别为行、列、通道数,其中 2 列的值再赋值为 255,用以下代码实现,效果展示如 1 下,黑色与白色的接壤的区域的像素值变化巨大。

从黑色到白色(0 到 255)的过渡是正斜率,而从白色到黑色(255 到 0)的过渡是负斜率。梯度指向增长率最大的方向,其大小是该方向上的斜率,可以通过灰度图像的梯度可以找到变化巨大的像素值。

图片

图1:黑白图像

图片

不考虑图像通道数的情况下,假设图像是二维离散函数 f(x,y),图像梯度是在 x 和 y 方向求导,求导之后的公式如图 2 下,使用求导公式对一个 3 行 3 列的二维数组求导,数组的值是 A 到 I,则对应 x 和 y 方向求导,如图 3 所示,其中常数可以忽略,x 方向求导可以看成两个数组相乘,如图 4 所示:

图片

图2:  梯度计算公式

图片

图3:  梯度计算上

图片

图4:梯度计算下

图 4 中的像素值和数字相乘的过程,与卷积操作非常像,数字类比卷积核,此处把这些数字称为模板。接下来,用代码实现 x 方向的图像梯度,先建立一个模板 dx,对应代码中的 kernel 数组,其数值是展示在图 5,再实现模板与图像像素值的相乘的过程,对应代码中的 filter2D 函数,代码实现如下,最后图 6 展示图像梯度的效果,找到了上图 1 中像素值剧烈变化的区域。

图片

图5:模板

图片

图6:梯度效果

图片

通过比较图像在水平和垂直方向像素值差异找到图像的边缘方法称为 Prewitt 算子,水平的算子模板 dx 和垂直的算子模板 dy 如图 7 所示,可以使用 OpenCV 中的 filter2D 函数实现 Prewitt 算子,代码如下,效果如图 8 所示。

图片

图7:Prewitt 算子模板

图片

图8:边缘检测效果

图片

2. 边缘检测(Sobel)

在 Prewitt 算子的基础上提高中心点的权重便是 Sobel 算子,中心点的权重为 2,其模板展示在图 9。

图片

图9:Sobel 算子模板

3. 边缘检测(Laplacian)

通过二阶导数的形式找到图像中的边缘便是 Laplacian 算子,图像的二阶导数展示在图10,其模板展示在图 11,OpenCV 中的 Laplacian 函数实现该算子,代码如下,效果如图 12 所示。

图片

图10:图像二阶导数

图片

图11:Laplacian算子模板

图片

图12:边缘检测效果

图片

3. 边缘检测(Canny)

以上的算子是找到图像中像素值变化巨大的区域,而这个变化巨大的区域不一定是边缘,面对这个不足,John.F.Canny 提出一个 Canny 边缘检测算法,它具有低错误率,检测出的边缘是真正的边缘;良好的定位,检测出的边缘像素点与真正边缘的像素点距离近;对噪声不敏感,噪声不应该标注为边缘。Canny边缘检测算法有四个步骤:

1. 降低对噪声的影响,对图像做高斯滤波或中值滤波,过滤噪声。

2. 使用Sobel算子对图像的每个像素点求梯度大小和方向。

3. 使用非极大值抑制算法在一组边缘中选取最好的边缘,具体做法是检查每个像素点与附近梯度方向一致的像素点,当前像素点梯度最大,则保留,否则去除。

4. 使用双阈值(小阈值, 大阈值)确定最终的边缘,像素点梯度高于大的阈值,则保留;像素点低于小的阈值,则忽略;介于两个阈值之间,判断像素点与边缘像素点是否相连。

OpenCV 中 cv2.Canny 函数可以进行 Canny 边缘检测,示例代码如下,效果展示在图13。

图片

图13:边缘检测效果

图片

关注+星标【CV算法恩仇录】

http://www.lryc.cn/news/140557.html

相关文章:

  • 【算法系列篇】前缀和
  • 若依移动端Ruoyi-App 项目的后端项目入门
  • (学习笔记-调度算法)内存页面置换算法
  • 行为型模式-观察者模式
  • 前端面试:【新技术与趋势】WebAssembly、Serverless、GraphQL
  • 【ubuntu】 20.04 网络连接器图标不显示、有线未托管、设置界面中没有“网络”选项等问题解决方案
  • SpringCloud/SpringBoot多模块项目中配置公共AOP模块实现打印子模块Controller所有请求参数与日志
  • 【GeoDa实用技巧100例】022:geoda生成空间权重矩阵(邻接矩阵、距离矩阵)
  • 基于web的鲜花商城系统java jsp网上购物超市mysql源代码
  • 意外发现Cortex-M内核带的64bit时间戳,比32bit的DWT时钟周期计数器更方便,再也不用担心溢出问题了
  • 数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。
  • 改进YOLO系列:6.添加ECA注意力机制
  • 软件测试知识点总结(一)
  • 持续集成与持续交付:现代软件测试的变革之路
  • 深度学习基本理论下篇:(梯度下降/卷积/池化/归一化/AlexNet/归一化/Dropout/卷积核)、深度学习面试
  • [Ubuntu 20.04] 通过udev规则修改网卡名称(例如eth0)
  • Java“牵手”根据关键词搜索(分类搜索)lazada商品列表页面数据获取方法,lazadaAPI实现批量商品数据抓取示例
  • Java—实现多线程程序 | 入门
  • 8.5 【C语言】指向函数的指针
  • C++实现字符串的逆置
  • 论Spring或Spring Boot的花式扩展
  • 如何评估分类模型的好坏
  • ● 84.柱状图中最大的矩形
  • 未检查的转换: ‘java.lang.Object‘ 转换为 ‘java.util.List
  • 【C语言】使用C语言,实现九九乘法表(另附Python、Java、JavaScript实现方式)
  • [机缘参悟-102] :IT人 - 管理的本质?管理人与从事技术的本质区别?人性、冰山模型、需求层次模型
  • [论文阅读笔记26]Tracking Everything Everywhere All at Once
  • 【Java 动态数据统计图】前后端对接数据格式(Map返回数组格式数据)六(120)
  • ❤ 给自己的mac系统上安装java环境
  • Java-匿名类