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

opencv-python常用函数解析及参数介绍(七)——边缘检测

边缘检测

  • 前言
  • 1.基本概念
    • 1) 滤波
    • 2) 计算梯度
    • 3) 非极大值抑制
    • 4) 双阈值检测
  • 2.opencv中的边缘检测
    • 效果展示
    • 分析对比
  • 3.结尾

前言

在之前的文章中我们介绍了使用膨胀和腐蚀、计算图像梯度的方式来获取图像的轮廓,本篇文章将介绍另外一种可以获取图像轮廓的方法——边缘检测

1.基本概念

首先我们来看一下边缘检测的基本过程

1) 滤波

使用高斯滤波器,以平滑图像,滤除噪声
在这里插入图片描述
H即为高斯分布的卷积核,初看上去似乎这个矩阵似乎很莫名其妙,但其实他的特征很明显,中间的数值要比周围的大,因为高斯滤波使用的卷积核是满足高斯分布,即正态分布的(是的,高斯分布就是正态分布)

关于高斯滤波的细节请参考之前的文章:opencv-python常用函数解析及参数介绍(三)——图像滤波

2) 计算梯度

计算图像中每个像素点的梯度强度和方向。

我们以3x3的sobel算子为例计算梯度
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在之前的文章中我们知道,sobel的梯度因为算子可以分成Sx和Sy,所以梯度也可以分为两个梯度,一个是Gx,更加侧重左右的偏差,即侧重竖直方向的边缘,而Gy更加侧重上下的偏差,即侧重水平方向的边缘,那么我们得到了x方向的梯度Gx,y方向的梯度Gy,那么总梯度应该为

G x 2 + G y 2 \sqrt{Gx^2+Gy^2} Gx2+Gy2
这里我们只求得了梯度的大小,那么如何计算梯度的方向呢

我们已经知道了x方向的梯度大小为Gx,y方向的梯度大小为Gy
假设梯度方向与 x 轴方向的夹角为 θ 则 t a n θ = G y G x 即 : θ = a r c t a n ( G y G x ) 假设梯度方向与x轴方向的夹角为 \theta \\则tan\theta = \frac{Gy}{Gx} \\ 即:\theta = arctan(\frac{Gy}{Gx}) 假设梯度方向与x轴方向的夹角为θtanθ=GxGy:θ=arctan(GxGy)

关于图像梯度的计算的详细细节可以参照上一篇博客:opencv-python常用函数解析及参数介绍(六)——图像梯度

3) 非极大值抑制

顾名思义就是抑制不是极大值的值,应用非极大值(Non-Maximum Suppression)抑制,以消除边缘检测带来的杂散响应。
在本问题中可以理解为只选用最大的梯度。

4) 双阈值检测

应用双阈值(Double-Threshold)检测来确定真实的和潜在的边缘。

其细节上表现为,设置两个阈值,一个阈值决定下限,另一个阈值决定上限,超过阈值上限的梯度可以理所应当的被认为是边缘,低于下限的梯度被认为不是边缘,而对应在上下限直接的范围梯度,应该看与他相连的梯度是不是已经被认为是边缘,如果已经被认为是边缘了,那么与边缘相连的也一定是边缘。

2.opencv中的边缘检测

上述的过程似乎有些复杂,幸好,在opencv中我们可以使用cv2.Canny进行边缘检测,我们只需设置双阈值检测中需要的上下限就好

效果展示

我们假设有一张名为kl.png的图片
在这里插入图片描述
为了展示方便,我们依然先编写一个展示函数

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

对这张图片进行边缘检测的效果如下

img=cv2.imread("kl.png",cv2.IMREAD_GRAYSCALE)

v1=cv2.Canny(img,80,150)
cv_show(v1,'res')

在这里插入图片描述

分析对比

与上篇文章中直接使用梯度当做边缘的效果相比似乎是更好的,那么这是为什么呢?其主要的区别就是从双阈值检测,因为我们进行了双阈值检测,在这个过程中当某一个点上的梯度小于设置的下限时就会被丢弃,即立即判断这个点不是边缘,所以相比之下,结果看起来会更干净(因为直接使用梯度作为边缘时一些较小梯度的点仍然会被保留)

当我们把下限设置成0时,即不对梯度的下限做限制,我们可以清晰的看到有些本不属于边缘的位置被当成了边缘

img=cv2.imread("kl.png",cv2.IMREAD_GRAYSCALE)
v1=cv2.Canny(img,0,150)
cv_show(v1,'res')

下面我们来对上下限进行修改,然后做一下对比

img=cv2.imread("kl.png",cv2.IMREAD_GRAYSCALE)

v1=cv2.Canny(img,0,150)
v2=cv2.Canny(img,50,150)
v3=cv2.Canny(img,50,200)

res = np.hstack((v1,v2,v3))
cv_show(cv2.resize(res, (1500, 500)),'res')

在这里插入图片描述

从这个对比中我们可以得到一个结论,上限相同时,降低下限,会导致被直接判断成非边界的点减少,从而得到更多的边缘,下限相同时,升高上限,会使得直接被判断成边界的点减少,同时也会影响到与被判断成边界的点相连的点,产生更少的边缘

3.结尾

关于边缘检测所需的内容,如果感兴趣可以参照之前的一个博客边缘检测生成(伪)手绘线稿风格的视频简易版教程自己生成一个边缘检测的(伪)线稿视频,关于图像的处理所用的全都是本专栏介绍过的知识

相关文章:

  • 14---实现文件上传和下载(头像上传功能)
  • Vue2学习笔记(四):计算属性(computed)和监事属性(watch)
  • 《信号与系统实验》实验 4:连续离散时间信号与系统的复频域分析实验
  • 【算法】kmp、Trie、并查集、堆
  • 2022年终总结与展望
  • (黑马C++)L06 重载与继承
  • Docker常用命令 - 黑马学习笔记
  • 抽象⼯⼚模式
  • 基于React Native开发的非法App破解记录
  • 年度征文 | 回顾2022,展望2023(我难忘的2022,我憧憬的2023)
  • JavaScript篇.day08-DOM,节点,事件,定时器,位置及坐标
  • QML教程(七) JavaScript
  • 蓝桥杯寒假集训第四天(全球变暖DFS)
  • VScode中不同目录间python库函数的调用
  • C语言版扫雷——从0到1实现扫雷小游戏
  • JS 中的深拷贝与浅拷贝
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • JavaScript实现分页效果
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • MYSQL如何对数据进行自动化升级--以如果某数据表存在并且某字段不存在时则执行更新操作为例...
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • node和express搭建代理服务器(源码)
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • Web Storage相关
  • 构建二叉树进行数值数组的去重及优化
  • 关于Flux,Vuex,Redux的思考
  • 解决iview多表头动态更改列元素发生的错误
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 区块链将重新定义世界
  • 微信小程序开发问题汇总
  • 以太坊客户端Geth命令参数详解
  • 函数计算新功能-----支持C#函数
  • #includecmath
  • (06)Hive——正则表达式
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (大众金融)SQL server面试题(1)-总销售量最少的3个型号的车及其总销售量
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (算法)Game
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (转)平衡树
  • ../depcomp: line 571: exec: g++: not found
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET MVC 验证码
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .php文件都打不开,打不开php文件怎么办
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • @TableLogic注解说明,以及对增删改查的影响
  • []C/C++读取串口接收到的数据程序
  • [C语言]一维数组二维数组的大小
  • [echarts] y轴不显示0
  • [ISCTF 2023]——Web、Misc较全详细Writeup、Re、Crypto部分Writeup