文章目录

  • 写在最前
  • Sobel 边缘检测
    • 基本原理
    • 代码实现
  • Canny边缘检测
    • 基本原理
    • 代码实现
  • Laplacian边缘检测
  • Scharr
  • 写在最后
    • 总结
    • 下载
    • 参考

写在最前

上一章节,我们在使用图像轮廓发现的时候使用了图像边缘检测,一次来提高图像轮廓发现的准确率。事实上在计算机的各个领域都有图像边缘检测的身影。边缘检测一大优点就在于可以大幅度减少数据量,并且提出可以认为不相关的信息,保留了图像的结构属性。边缘检测的方法有很多,但是绝大部分都可以分为两大类,第一类是基于搜索,也就是通过寻找图像一阶导数中的最大值和最小值来检测边界,通常是定位在梯度最大的方向。其次是基于零穿越的方法,其通过寻找图像二阶导数零穿越来寻找便捷,通常是Laplacian过零点或者非线性差分表示的过零点。(以下内容引用自百度百科

边缘可能与视角有关—— 也就是说边缘可能随着视角不同而变化,典型地反映在场景、物体的几何形状一个将另一个遮挡起来,也可能与视角无关——这通常反映被观察物体的属性如表面纹理和表面形状。在二维乃至更高维空间中,需要考虑透视投影的影响。

在我们需要检测表面纹理和表面形状时,我们往往需要更细致的检测,比如基于二阶导数的Canny,但是很多时候简单的基于一阶导数的算子想过可能更好。不同的算子由于其具体算法不同,实际效果也存在比较大的差距。具体情况还需要具体处理。

Sobel 边缘检测

基本原理

Sobel算子是几种边缘检测算子中最简单的,其由两组3*3矩阵组成(这里用水平矩阵sobelx,垂直矩阵sobely表示)。将两组算子与图像(这里用A表示)做平面卷积就可以的得到垂直和水平的亮度差分近似值。然后Gx=sobelx*AGy=sobely*A,最终得到的结果就是:
Gx=Gx2+Gy22G_x=\sqrt[2]{G_x^2+G_y^2} Gx​=2Gx2​+Gy2​​
Sobel相比于其他算子的优势在于比较简单和快速,只需要三次简单运算就可以得到(Sobel需要灰度图,所以更准确的说想要使用Sobel还需要灰度图转换的步骤)。同时Sobel也可以只检测垂直方向或者只检测水平方向。因此当我们不需要注意细纹理或者只需要单方向检测的时候不妨使用一下Sobel。

下面是Sobel在OpenCV中的实现,这里我们还是使用之前的OpenCV中自带的水果分尸图,下面是核心代码,经过了这么多次的我们就不再多写数据加载,灰度转换,窗口等待这些基本内容了:

代码实现

# 使用sobel算子并进行边缘检测
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1)sobelx = numpy.uint8(numpy.absolute(sobelx))
sobely = numpy.uint8(numpy.absolute(sobely))# 得带最终结果
sobelcombine = cv2.bitwise_or(sobelx,sobely)# 展示效果并保存
cv2.imshow("Edge detection by Sobel", numpy.hstack([gray,sobelx,sobely, sobelcombine]))
cv2.imwrite("1_edge_by_sobel.jpg", numpy.hstack([gray,sobelx,sobely, sobelcombine]))

Canny边缘检测

基本原理

以下内容引用自百度百科

Canny边缘检测算子是John F. Canny于1986年开发出来的一个多级边缘检测算法。更为重要的是Canny创立了“边缘检测计算理论”(computational theory of edge detection)解释这项技术如何工作。

Canny的目标是找到一个最优的边缘检测算法,而这个最优边缘检测算法的含义是指三个方面:

  • 好的检测- 算法能够尽可能多地标识出图像中的实际边缘。
  • 好的定位- 标识出的边缘要与实际图像中的实际边缘尽可能接近。
  • 最小响应- 图像中的边缘只能标识一次,并且可能存在的图像噪声不应标识为边缘。

为了满足这些要求Canny使用了变分法,这是一种寻找满足特定功能的函数的方法。最优检测使用四个指数函数项的和表示,但是它非常近似于高斯函数的一阶导数。

为了得到最好的结果,Canny算子需要多个步骤,第一步是降噪,任何一个边缘检测算法都不可能在一个没有经过降噪的图片上得到好的结果。Canny的第一步是进行高斯平滑操作,这样可以有效避免少量噪音像素对最终结果造成不好的影响。

第二步是寻找梯度,为了在各个方向更好地寻找梯度,Canny算法使用4个mask寻找水平,垂直和对角线方向的边缘(可以和Sobel的两种作对比),这样和Sobel类似,可以得到图像中每个像素的亮度梯度图以及亮度梯度的方向图。

第三步是跟踪边缘,较亮的亮度梯度更有可能是边缘,但是较亮的亮度梯度并不一定都是边缘,有些亮度梯度比较明亮可能是真正的边缘,有些则可能不是。所以Canny使用了滞后阈值,滞后阈值由两个阈值——高阈值和低阈值共同组成,我们需要同时使用他们来确定真正的边缘。

首先假设图像中的重要边缘都是连续的曲线。那么我们首先根据求导得到的方向信息,用一个较大的阈值标识出我们比较确信的真实边缘,然后使用一个较小的阈值来扩展这些已经定了的真实边缘。由于我们假设重要边缘都是连续的曲线,那么也就意味着只要我们不断地沿着最可能是真实边缘的方向(最亮梯度方向)不断延长我们的真实边缘,直到到达下一个最亮梯度达到最小阈值,这样能够最终获得一个完美的曲线来表示我们想要寻找的重要边缘。当整个过程完成,我们就得到了一个二值图像,每点表示是否是一个边缘点。

除此之外,还有一个获得亚像素精度边缘的改进实现是在梯度方向检测二阶方向导数的过零点。这里我们不再进行详细描述。

但是通过对Canny算法的具体了解,我们得到了两个重要的内容就是有两个核心的参数可以有效的影响Canny边缘检测的效果。一个是第一步的高斯平滑,第二是第三步的阈值设置。我们上一篇文章末尾的例子(opencv自带的例子)就是使用的Canny算子进行的边缘检测的展示。其中也包含了这两个核心的设置,模糊和阈值。

代码实现

为了方便演示我们来写一个更简单的例子:

canny = cv2.Canny(gray, 30, 150)canny = numpy.uint8(numpy.absolute(canny))
#display two images in a figure
cv2.imshow("Edge detection by Canny", numpy.hstack([gray,canny]))

写到这你可能很奇怪,为什么这里Canny也是使用的灰度图,我们上一次演示不是在彩色图片上绘制出的边缘吗?这是因为之前的demo思路和之前的图像轮廓获取一致的。都是在获取要检测的内容之后,将结果绘制在了原来的彩色图片上。而且要注意的是这些demo中的阈值都是可以调节的哦,具体请见下图:


其中第一幅图片的高低阈值比例是固定的,而第二幅图片没有固定高低阈值,我们可以手动调节查看具体效果。这两个更详细的demo都是opencv自带的例子,尤其第二个是可以实时从摄像头获取数据并检测绘制的。我们之前还没有接触过有关的内容,但是之后的章节将会不断接触。

Note:你可以前往我的github——漫谈计算机视觉下载有关代码。

Laplacian边缘检测

Laplacian 算子是n维欧几里德空间中的一个二阶微分算子,可以用于图像增强或者边缘提取。效果和之前的差别不大,和Canny一样属于二阶算法,但是由于要计算梯度,OpeCV的Laplacian算子内部也使用了Sobel,同时他又和Canny一样进行了多个方向上的梯度检测,因为复杂度更好,细纹理的发现效果更好。由于篇幅原因这里不再多讲,直接看效果就好。

ap = cv2.Laplacian(gray, cv2.CV_64F,ksize=3)Laplacian = cv2.convertScaleAbs(lap)
# 等价于上面的代码
# Laplacian = numpy.uint8(numpy.absolute(lap))#display two images in a figure
cv2.imshow("Edge detection by Laplacaian", numpy.hstack([gray,Laplacian]))

Scharr

OpenCV还有一个边缘检测Scharr,其主要是为了配合Sobel,下面代码是等价的。

Scharr(src,dst,ddepth,dx,dy,scale,delta,borderType)
sobel(src,dst,ddepth,dx,dy,CV_SCHARR,scale,delta,borderType)

写在最后

总结

边缘检测是OpenCV中比较多的内容,完全可以铺开讲很多,但是考虑到该部分在当前的计算机视觉领域已经不算重点,所以这里没有讲太多。但是万变不离其宗,所以我们重点讲述了一个一阶算法Sobal,一个二阶算法Canny,同时也代码展示了OpenCV中的其他元素。希望这些能够有所帮助。

而除了边缘检测,OpenCV中还有一类名字有点接近边缘检测的检测器,那就是角点检测。角点检测使用范围将会更广。下次我们将从角点检测谈起,说说更复杂的内容。

下载

Note:你可以前往我的github——漫谈计算机视觉下载有关代码。

参考

  1. 百度百科-边缘检测

  2. OpenCV-github官方项目

图像边缘检测,检测亦或简化相关推荐

  1. c语言sobel边缘检测,Sobel图像边沿检测算法的优化设计与实现

    0 引言 图像边沿是图像的基本特征,是图像分割.特征提取等图像分析的重要依据,目前已广泛应用于目标识别.机器视觉和运动目标跟踪等领域.现今已有多种边沿检测算法以及一些改进方式,但各种算法都有各自的优缺 ...

  2. 砍掉九成代码,重构并简化YOLOv5图像目标检测推理实现

    YOLOv5官方开源代码给出了完成的推理实现,但过于封装,只能通过修改配置参数对指定文件夹下图像和视频进行推理,而且三百多行的推理代码也显得过于冗长.如果想要在项目上进行部署应用,显然需要更高的灵活性 ...

  3. 基于分数阶的图像边缘细节检测

    1 分数阶微分理论 分数阶微分几乎和整数阶微分同时诞生,但由于一直没有常见的物理现象能够解释这一数学表达式的含义,所以其也未被广泛运用.几个世纪以来,虽然分数阶微分理论得到了长足的发展,但至今没有统一 ...

  4. 基于小波的图像边缘检测,小波变换边缘检测原理

    1.什么是"小波神经网络"?能干什么用呀 小波神经网络(Wavelet Neural Network, WNN)是在小波分析研究获得突破的基础上提出的一种人工神经网络.它是基于小波 ...

  5. sobel算子原理_「学术论文」基于Sobel算法图像边缘检测的FPGA实现

    摘要: 针对嵌入式软件无法满足数字图像实时处理速度问题,提出用硬件加速器的思想,通过FPGA实现Sobel边缘检测算法.通过乒乓操作.并行处理数据和流水线设计,大大提高算法的处理速度.采用模块的硬件设 ...

  6. 遥感图像目标检测研究综述

    遥感图像目标检测 遥感图像特殊性 一.目标检测研究综述 1.介绍 2.传统目标检测 3.基于深度学习目标检测 R-CNN系列为代表的两阶段算法 YOLO.SSD为代表的一阶段算法 二.多尺度目标检测研 ...

  7. 基于FPGA的实时图像边缘检测系统设计(上)

    今天给大侠带来基于FPGA的实时图像边缘检测系统设计,由于篇幅较长,分三篇.今天带来第一篇,上篇,话不多说,上货. 导读 随着科学技术的高速发展,FPGA在系统结构上为数字图像处理带来了新的契机.图像 ...

  8. CV笔记6:图像边缘检测之一阶微分算子、二阶微分算子、Canny边缘检测(基于python-opencv实现)

    目录 一.边缘简介 1.1 何为边缘 1.2 产生原因 二.边缘检测方法 2.1 一阶微分算子计算原理 2.2 噪声对一阶微分算子的影响及解决方案 2.3 常见的一阶微分算子 2.3.1 Robert ...

  9. 图像边缘检测——一阶微分算子 Roberts、Sobel、Prewitt、Kirsch、Robinson

    图像为什么会有边缘? 图像边缘一般指图像的灰度变化率最大的位置.成因主要如下: 1.图像灰度在表面方向变化不连续: 2.图像中物体在空间上的深度不一致: 3.在光滑的表面上颜色不一致: 4.图像中物体 ...

最新文章

  1. java 模拟时钟_java模拟时钟
  2. 如何做一名优秀的博士生--施一公教授
  3. nyoj--586(疯牛) poj --2456
  4. 在URL参数中传递复杂对象
  5. 三角形一条边在另一条的投影长度计算
  6. Python学习笔记:集成开发环境
  7. 2021年净利润同比增长75.9% 孟晚舟称华为已穿过劫难黑障区
  8. 修改sublime 侧边栏 颜色 等
  9. 达观杯文本智能处理(1)
  10. python脚本根据cookies自动登录网站_为爬虫获取登录cookies:使用万能钥匙 Selenium 搞定一切登录...
  11. 评论字数限制php,WordPress评论字数限制
  12. 高性能实现WORD转PDF(jacob1.19+SaveAsPDFandXPS)内附资源链接
  13. 深度学习(二),终于理解了深度学习原理--SPGD(SGD)优化算法的实现原理
  14. Apache Ignite
  15. 绘制业务流程图—入门篇
  16. 用python写一个躲避球十分简单的小游戏
  17. 学习信奥要不要先学python
  18. 火影忍者379在线观看
  19. Excel的VLOOKUP函数及其用法
  20. 通过PS把月亮装进灯泡里打造创意灯泡月亮

热门文章

  1. setlocal启动批处理文件中环境变量的本地化
  2. 《银翼杀手2049》:活着不只为了“存在”
  3. hadoop jetty的应用
  4. 基于WinSvr2016(TP)构建的“超融合技术架构”进阶篇
  5. JavaScript计算汉明距离(HammingDistance)
  6. 35+的互联网人都哪去了
  7. 写的很好!细数 Java 线程池的原理
  8. 为了做到微服务的高可用,鬼知道我出了多少张牌
  9. 没有文档,没有老员工讲解,悲催的新人如何快速熟悉一个新项目?
  10. 聊聊并发-Java中的Copy-On-Write容器