图像处理算法 之 梯度/边缘检测(Sobel算子,拉普拉斯算子,Canny等)

2023-11-09

梯度是一个量变化的速度,在数学中通常使用求导、求偏导获取梯度或者某一方向上的梯度。
在数字图像中梯度可以看为像素值分别在x,y方向上的变化速度,因为数字图像的离散型,以及像素是最小处理单元的特性,求数字图像的梯度时,不需要求导,只需要进行加减运算即可。(其实就是求导的差分近似形式).如下图所示:
在这里插入图片描述

这就使得可以通过简单的卷积运算得到图像的边缘信息。
因此就有了一些基本的梯度算子:Sobel算子、Scharr算子、Roberts算子、拉普拉斯算子,都属于一阶微分算子

一、一阶微分算子

1.1 Sobel算子

在这里插入图片描述
如上式,G_x 与G_y 分别表示对图像A进行横向和纵向梯度检测得到的结果。(注意,是横向的梯度,不是横向的边缘
取二者平方和即可得到图像上每一点的梯度值,即在该点同时计算x方向与y方向的梯度。
在这里插入图片描述
该点的梯度方向可以通过取这两个值的比的反正切arctan得到:
在这里插入图片描述
前面也说了,Sobel算子并不是真正的导数,只是对函数的差分近似,或者说是局部拟合,而差分近似的阶数越高,拟合就更加准确。因此大的核能够更好的近似导数,可以消除部分噪声影响。但是导数变化比较剧烈时,核太大会导致结果偏差大。

1.2 Scharr算子

Scharr算子是Sobel算子的一种特殊形式。
其核的形式如下:
在这里插入图片描述
前面提到了,Sobel算子中核越大就能够更好的近似导数,准确度也更高。因此,在核比较小时如3×3时,Sobel核的准确度较差,使用Scharr算子代替3×3的Sobel核能够提高精度。因为加大了在x方向或y方向的权重,使得梯度角(梯度方向)不会距离x或y方向太远,因此误差也不会太大。例如,只求x方向的梯度时,核的中心点的x方向的两个权值远大于其它权值,这使得求得的梯度更靠近x方向,一定程度减小了误差。

OpenCV函数使用:
void cv::Sobel(
cv::InputArray src,
cv::OutputArray dst,
int ddepth, //输出图的深度或类型
int xorder, //求导顺序取值可为:0,1,2 。0表示不求导
int yorder, //同上
cv::Size ksize = 3,//核大小,必须为奇数
double scale = 1,
double delta = 0,
int borderType = cv::BORDER_DEFAULT
)

将ksize 设为cv::SCHARR可转为使用Scharr算子

1.3 Roberts算子

在这里插入图片描述
Roberts算子的核如上图所示,是一种简单的交叉差分算法,在求±45°的梯度时最有效。
相比于一般的水平竖直方向的差分算子,Roberts算子能够有效地保留边缘的角点,并且计算速度较快。缺点是对细节敏感导致对噪声也十分敏感。

一阶微分算子即是对图像的灰度变化情况进行求导,获得的边缘比较粗糙,并且信息较少。二阶微分算子是对灰度变化的导数求导,对灰度值变化更为敏感,获得的边缘更加准确。

二、二阶微分算子

2.1 拉普拉斯算子

拉普拉斯算子可由二阶导数定义:
在这里插入图片描述
而在数字图像中离散化,用二阶差分表示为:
在这里插入图片描述
所以拉普拉斯算子可以表示为:
在这里插入图片描述
其卷积核如下图所示:
在这里插入图片描述
拉普拉斯算子法其实是一种图像边缘增强算子,常用于图像锐化,在增强边缘的同时也增强了噪声,因此使用前需要进行平滑或滤波处理
如下图,可以看出,在函数值发生突变的情况时,二阶导数能够增强突变点与其两侧的对比度。在数字图像中就是图像边缘处得到了增强,因此实现了图像的锐化。
在这里插入图片描述

OpenCV函数使用
Void cv::Laplacian(
cv::InputArray src,
cv::OutputArray dst,
int ddepth,
cv::Size ksize = 3,
double scale = 1,
double delta = 0,
int borderType = cv::BORDER_DEFAULT
);

其实二阶微分算子还有LOG的,但其实和拉普拉斯算子差别不是特别大,就不再详细进行说明了

二阶微分算子检测的边缘更加准确,对边缘的定位能力更强。但是相较于一阶微分算子,不能保留梯度的方向信息,并且对噪声更为敏感。 1986年提出Canny算子能够较好的兼顾这几方面,成为最常用也最有效稳定的边缘检测算法。

三、Canny算法

算法流程

去噪。使用高斯滤波对图像进行平滑去除噪声。滤波详情可见
https://blog.csdn.net/qq_38574198/article/details/109030375
检测初始边缘。使用Sobel算子进行边缘检测,得到初始的边缘信息。
非极大值抑制细化。利用非极大值抑制算法,只保留局部极大梯度,抑制其它非极大的梯度。
在Sobel算子进行边缘检测后得到的边缘图可以视为梯度图,每个位置的梯度大小可以根据其灰度值得到
如图,点C处的梯度方向为蓝线,然后对比C点的灰度值与其正负梯度方向上相邻位置(点dTmp1和dTmp2)的灰度值,只有当C的灰度值大于其它两个点的灰度值时,才视C点为边缘点,否则将其置0. 而因为正负梯度方向上的位置不一定正对单个像素点,这两个位置的灰度值往往通过其相邻的点进行线性插值得到。例如g1,g2插值得到dTmp1的灰度值
在这里插入图片描述
双阈值筛选
定义一个高阈值和一个低阈值。梯度强度低于低阈值的像素点被抑制,不作为边缘点;高于高阈值的像素点被定义为强边缘,保留为边缘点;处于高低阈值之间的定义为弱边缘,留待进一步处理。
边缘连接(孤立点筛选)
因为还是有部分噪声的存在,噪声在梯度图中算是 “假边缘“。通常而言,由真实边缘引起的弱边缘像素点将连接到强边缘像素点,而噪声响应则未连接。通过查看弱边缘像素及其8个邻域像素,可根据其与强边缘的连接情况来进行判断。一般,可定义只要其中邻域像素其中一个为强边缘像素点,则该弱边缘就可以保留为强边缘,即真实边缘点。

OpenCV 函数使用

Void cv::Canny(
Cv::InputArray image, //输入图片,必须单通道格式
Cv::OutputArray edges, //输出
Double threshold1, //双阈值中的低阈值
Double threshold2, //高阈值
Int apertureSize = 3, //Sobel算子处理的核的大小
Bool L2gradient = false //计算方向梯度时使用1范数(快,精度较低)还是2范数(精度高)
)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图像处理算法 之 梯度/边缘检测(Sobel算子,拉普拉斯算子,Canny等) 的相关文章

  • 查找彼此接近的对象边界

    我正在研究一个计算机视觉问题 其中问题的第一步是找到物体彼此靠近的位置 例如 在下图中 我感兴趣的是找到灰色标记的区域 Input Output 我目前的方法是首先反转图像 然后通过侵蚀进行形态梯度跟随 然后删除一些不感兴趣的轮廓 脚本如下
  • 如何在opencv python中为图像添加边框

    如果我有如下图所示的图像 如何在图像周围添加边框 以便最终图像的整体高度和宽度增加 但原始图像的高度和宽度保持在中间 下面的代码添加了一个大小恒定的边框10像素到原始图像的所有四个边 对于颜色 我假设您想要使用背景的平均灰度值 这是我根据图
  • 我是否必须使用我的数据库训练 Viola-Jones 算法才能获得准确的结果?

    我尝试提取面部数据库的面部特征 但我认识到 Viola Jones 算法在两种情况下效果不佳 当我尝试单独检测眼睛时 当我尝试检测嘴巴时 运作不佳 检测图像的不同部分 例如眼睛或嘴巴 或者有时会检测到其中几个 这是不可能的情况 我使用的图像
  • 使用opencv计算深度视差图

    我无法使用 opencv 从视差图计算深度 我知道两个立体图像中的距离是用以下公式计算的z baseline focal disparity p 但我不知道如何使用地图计算视差 我使用的代码如下 为我提供了两个图像的视差图 import n
  • 在 QtCreator 中将 OpenCV 2.3 与 Qt 结合使用

    随着 OpenCV 2 3 版本终于发布 我想在我的系统上编译并安装这个最新版本 由于我经常使用 Qt 和 QtCreator 我当然希望能够在我的 Qt 项目中使用它 我已经尝试了几种方法几个小时 但总是出现错误 第一次尝试 使用WITH
  • 如何将 mat 转换为 array2d

    我为dlib http dlib net face landmark detection ex cpp html那里的面部地标代码使用 array2d 来获取图像 但我喜欢使用 Mat 读取图像并转换为 array2d 因为 dlib 仅支
  • opencv形态扩张滤波器作为最大滤波器

    就像中值滤波器的定义一样 我可以将 最大滤波器 定义为局部窗口 例如dst x y max 3x3 局部窗口像素 但我在opencv中找不到这样的过滤器 最接近的是 dilate 函数 然后我使用 dilate 函数的默认配置 但结果不正确
  • OpenCV 3 中的 FLANN 错误

    我运行的是 Ubuntu 14 04 我正在尝试使用 openCV 3 运行 FLANN 但出现错误 下面的所有内容都是通过使用 AKAZE 和 ORB 进行尝试的 但代码来自我尝试使用 ORB 的情况 我使用 ORB 来查找描述符和关键点
  • 如何将输出视频保存到 OpenCV 中的文件中

    我想将输出视频保存到文件中而不是显示它并尝试使用 cvcaptureimage 但仍然无法获得结果 include
  • 使用 ffmpeg 或 OpenCV 处理原始图像

    看完之后维基百科页面 http en wikipedia org wiki Raw image format原始图像格式 是任何图像的数字负片 为了查看或打印 相机图像传感器的输出具有 进行处理 即转换为照片渲染 场景 然后以标准光栅图形格
  • 如何去除给定图像中的噪声,使 ocr 输出完美?

    我已经对这个孟加拉文本图像进行了大津阈值处理 并使用 tesseract 进行 OCR 但输出非常糟糕 我应该应用什么预处理来消除噪音 我也想校正图像 因为它有轻微的倾斜 我的代码如下 import tesserocr from PIL i
  • OpenCV IP 相机应用程序崩溃 [h264 @ 0xxxxx] 访问单元中缺少图片

    我在 cpp 中有一个 opencv 应用程序 它使用 opencv 的简单结构捕获视频流并将其保存到视频文件中 它与我的网络摄像头完美配合 但是 当我运行它从 IP 摄像机捕获流时 它可能会在大约十秒后崩溃 我的编译命令是 g O3 IP
  • 如何使用 Python 裁剪图像中的矩形

    谁能给我关于如何裁剪两个矩形框并保存它的建议 我已经尝试过这段代码 但效果不佳 import cv2 import numpy as np Run the code with the image name keep pressing spa
  • 如何确定与视频中物体的距离?

    我有一个从行驶中的车辆前面录制的视频文件 我将使用 OpenCV 进行对象检测和识别 但我停留在一方面 如何确定距已识别物体的距离 我可以知道我当前的速度和现实世界的 GPS 位置 但仅此而已 我无法对我正在跟踪的对象做出任何假设 我计划用
  • 如何绘制更大的边界框和仅裁剪边界框文本 Python Opencv

    我正在使用 easyocr 来检测图像中的文本 该方法给出输出边界框 输入图像如下所示 Image 1 Image 2 使用下面的代码获得输出图像 But I want to draw a Single Bigger bounding bo
  • 在 Visual Studio 2012 中安装 OpenCV

    我正在尝试安装 OpenCV 来与 Visual Studio 一起使用 我使用的是2012Pro版本 但我认为它应该与vs10相同 我正在关注这个教程 http docs opencv org doc tutorials introduc
  • cv2.VideoWriter:请求一个元组作为 Size 参数,然后拒绝它

    我正在使用 OpenCV 4 0 和 Python 3 7 创建延时视频 构造 VideoWriter 对象时 文档表示 Size 参数应该是一个元组 当我给它一个元组时 它拒绝它 当我尝试用其他东西替换它时 它不会接受它 因为它说参数不是
  • 是否可以在 PyScript 中使用 OpenCV 模块?

    我想使用 opencv 模块 但无法导入 OpenCV 那么我该如何解决这个问题呢 顺便说一句 Pyodide 支持 OpenCV 示例代码 https i stack imgur com ahwex jpg 尚不支持 OpenCV 此时O
  • OpenCV VideoWriter 未写入 Output.avi

    我正在尝试编写一段简单的代码来获取视频 裁剪视频并写入输出文件 系统设置 OS Windows 10 Conda Environment Python Version 3 7 OpenCV Version 3 4 2 ffmpeg Vers
  • “没有名为‘cv2’的模块”,但已安装

    我已经安装了包含 opencv 贡献的 whl 文件 因为我想使用 SIFT 算法 我在 conda 环境中使用 pip 安装了它 所以当我在 conda list 中提示时 它会向我显示 opencv python 3 4 5 contr

随机推荐

  • sh: 1: pause: not found

    linux下运行c 程序时 希望控制台不会输出后马上消失 在windows系统下 用如下语句 include
  • redis-benchmark 基准测试

    redis benchmark 基准测试 大家好 我是爱吃鱼的程序员 一个渴望在互联网行业做到C位的程序员 可柔可刚 点赞则柔 白嫖则刚 看完记得给我来个三连哦 欢迎私信 1 概述 当我们希望提高性能的使用 往往想到的是异步 缓存这个两种手
  • nginx部署的时候出现403错误

    nginx部署的时候出现403错误 原因 启动用户和nginx工作用户不一致所致 解决方法 1 先查看当前的启动用户 命令 ps aux grep nginx worker process awk print 1 这样就是启动用户和工作用户
  • Linux下多线程调试的一些方法

    一直觉得Linux下的多线程调试是很麻烦的 因为一般大一点的程序线程会很多 通过gdb的info thread命令看全都是系统调用 看不到详细的方法 至少我看到是这样的 如果用thread id跟进每个thread去bt 是件相当痛苦的事情
  • 关于spring-boot中的@SpringBootApplication中的@ComponentScan的basePackages的路劲的设置。...

    最近在看spring boot的东西 然后搭建了spring boot的简单项目 但是在spring的入口处加载的时候一直加载不到 最后看了 SpringBootApplication的源码才知道 ComponentScan 如果不设置ba
  • ChatGPT教程:如何优化我们编写的Python代码?

    背景介绍 作为一名程序员 我们经常需要编写Python代码 然而 代码质量的好坏直接关系到程序的可读性 可维护性和可扩展性 因此 我们需要使用一些工具来帮助我们提高代码质量 ChatGPT是一种强大的自然语言处理模型 可以帮助我们完成这项任
  • 全面接入:ChatGPT杀进15个商业应用,让AI替你打工

    智东西 智能产业新媒体 智东西专注报道人工智能主导的前沿技术发展 和技术应用带来的千行百业产业升级 聚焦智能变革 服务产业升级 ChatGPT狂飙160天 世界已经不是两个月前的样子 文 李水青 编辑 心缘 来源 智东西 ID zhidxc
  • findbug类型

    Summary Description Category BC Equals method should not assume anything about the type of its argument Bad practice BIT
  • 十九、SpringAOP切面的单例与多例

    Repository Scope prototype public class UserDao implements IUserDao public void save System out println 保存成功 无返回值 Config
  • 硬件基础——滤波

    一 滤波概念 滤波是将信号中特定波段频率滤除的操作 是抑制和防止干扰的一项重要措施 滤波器分类 1 当允许信号中较高频率的成分通过滤波器时 这种滤波器叫做高通滤波器 2 当允许信号中较低频率的成分通过滤波器时 这种滤波器叫做低通滤波器 3
  • vue echarts 三维折线图

    效果图
  • USR-WIFI232-B2(WIFI)模块没有和服务器TCP连接成功时,单片机读取USR-WIFI232-B2(WIFI)模块的MAC地址

    您想要实现什么功能 1 单片机上电后先读取WIFI模块的MAC地址 2 读取完WIFI模块的MAC地址的后 WIFI模块和上位机进行TCP通信 WIFI模块作为服务器 需要发送 a 进入AT指令配置状态 读取MAC 读取之后 发送AT EN
  • 用HL7创建含多个code item的modality worklist

    需求 DCM4CHEE做RIS DICOM服务器 用NHAPI发ORM o01消息创建worklist 问题 在同一个OBR里面没法包含多个Scheduled Protocol Code Sequence item 创建出来的worklis
  • kafka介绍

    一 kafka介绍 1 1 kafka 模型介绍 Kafka 是一个开源的 轻量级的 支持多分区 多副本 基于 Zookeeper 的分布式消息流平台 相比于其它消息系统 其有以下优点 支持发布订阅模式的消息引擎系统 储存数据流时提供容错机
  • 直观了解CNN

    CNN解释器 https poloclub github io cnn explainer GitHub https github com poloclub cnn explainer 论文 https arxiv org abs 2004
  • Buck电路的参数计算及仿真

    一 Buck电路的参数计算较为简单 可以用matlab来完成 代码如下 clear clc Vin 12 输入电压单位V Vout 5 输出电压单位V Fs 100000 开关频率单位Hz DeltaIL 0 25 电流纹波单位A Delt
  • 实战DeviceIoControl 之五:列举已安装的存储设备

    Q 前几次我们讨论的都是设备名比较清楚的情况 有了设备名 路径 就可以直接调用CreateFile打开设备 进行它所支持的I O操作了 如果事先并不能确切知道设备名 如何去访问设备呢 A 访问设备必须用设备句柄 而得到设备句柄必须知道设备路
  • nginx基础3——配置文件详解(实用功能篇)

    文章目录 一 平滑升级 二 修饰符 2 1 无修饰符效果 2 2 精准匹配 2 3 区分大小写匹配 2 4 不区分大小写匹配 2 5 匹配优先级 三 访问控制 四 用户认证 五 配置https 六 开启状态界面 七 rewrite重写url
  • [ 未完结 ] [ 小程序 lin-ui 分析 1]总起 资源导航栏

    最近由于学校项目一直在做小程序 实习那边刚好事情不是很多 就将研究重心放在了小程序上 lin ui是一位师兄在21年10月推荐给我的 当时我还是第一次独自一人负责小程序开发 那个时候csdn里面关于lin ui文章并不是很多 我自己在上手l
  • 图像处理算法 之 梯度/边缘检测(Sobel算子,拉普拉斯算子,Canny等)

    边缘检测 一 一阶微分算子 1 1 Sobel算子 1 2 Scharr算子 OpenCV函数使用 1 3 Roberts算子 二 二阶微分算子 2 1 拉普拉斯算子 OpenCV函数使用 三 Canny算法 算法流程 OpenCV 函数使