《OpenCV计算机视觉》—— 图像边缘检测

文章目录

  • 一、图像边缘检测概述
  • 二、常见的图像边缘检测算法(简单介绍)
    • 1.sobel算子
    • 2.Scharr算子
    • 3.Laplacian算子
    • 4.Canny算子
  • 三、代码实现

一、图像边缘检测概述

  • 图像边缘检测是一种重要的图像处理技术,用于定位二维或三维图像中对象的边缘。这些边缘通常是图像中亮度或灰度值发生显著变化的地方,对应着物体的轮廓不同区域的边界
  • 图像边缘检测在图像分割、目标识别、图像分析等领域具有广泛的应用
  • 图像边缘检测的目的
    • 特征提取:边缘是图像中重要的特征信息,通过边缘检测可以提取出这些特征,为后续处理如图像分割、目标识别等提供基础。
    • 图像简化:边缘检测后的图像更为简洁,去除了大量冗余的像素点,有助于减少计算量,提高处理速度,并使图像更易于分析和理解。
    • 结构分析:边缘检测有助于分析图像中的结构信息,如物体的形状、大小、方向等,这些信息对于图像理解、场景重建等任务至关重要。
    • 提升图像质量:边缘检测可以突出图像中的轮廓信息,使图像更加清晰、易于观察,特别是在医学影像分析、遥感图像处理等领域尤为重要。
    • 促进后续处理:边缘检测是许多图像处理任务的预处理步骤,如图像分割、目标检测、目标跟踪等,通过边缘检测可以更容易地识别出图像中的目标对象,并为后续处理提供准确的定位信息。
  • 图像边缘检测的基本步骤
    • 滤波:边缘检测算法主要基于图像强度的一阶和二阶导数,但这些导数对噪声非常敏感。因此,滤波是边缘检测前的必要步骤,以减少噪声对边缘检测结果的影响。常用的滤波器有高斯滤波器,它通过离散化的高斯函数对图像进行平滑处理。
    • 增强:增强算法的目的是将图像中灰度有显著变化的点(即潜在的边缘点)凸显出来。一般通过计算梯度幅值来完成,梯度反映了亮度变化的强度和方向。
    • 检测:在增强后的图像中,需要进一步检测边缘点。常用的方法是通过阈值化来检测边缘点,即设定一个或多个阈值,将梯度幅值大于阈值的点视为边缘点。
    • 定位:在检测到边缘点后,需要进一步确定边缘的精确位置。这通常涉及到对边缘点的进一步处理和分析,如亚像素边缘定位等,以提高边缘检测的精度。
    • 连接:在某些情况下,由于噪声、光照变化等因素的影响,检测到的边缘点可能会呈现为断开的片段。因此,需要通过一定的算法(如霍夫变换、轮廓跟踪等)将这些断开的边缘片段连接起来,形成完整的边缘轮廓。

二、常见的图像边缘检测算法(简单介绍)

1.sobel算子

  • Sobel 算子是一种离散的微分算子,该算子结合了高斯平滑微分求导运算。该算子利用局部差分寻找边缘,计算所得的是一个梯度的近似值。
  • Sobel算子包含2组3×3的矩阵,分别为横向(Y方向)纵向(X方向)模板,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。
  • 如下图所示卷积核沿着X和Y方向进行卷积
    在这里插入图片描述

2.Scharr算子

  • Scharr 算子是 Soble 算子在 ksize=3 (卷积核为3*3)时的优化,卷积核比Sobel算子更精细,与 Soble 的速度相同,且精度更高。Scharr 算子与 Sobel 算子的不同点是在平滑部分,其中心元素占的权重更重,相当于使用较小标准差的高斯函数,也就是更瘦高的模板。
  • 卷积核如下:
    在这里插入图片描述
  • 以上两种算子的检测过程如下图所示
    在这里插入图片描述

3.Laplacian算子

  • Laplacian算子不再以x和y的方向计算,而是以圆方向计算变化率。因此不需要Gx+Gy。
  • 卷积核类似下图:
    在这里插入图片描述

4.Canny算子

  • Canny算子是一种多步骤的边缘检测算法,它通过图像平滑(降噪)计算梯度幅值和方向非极大值抑制以及双阈值处理等多个步骤来提取边缘信息
  • 因此Canny算子具有高精度低误检率抗噪声能力强的特点,是许多图像处理任务中边缘检测的首选算法
    • 图像降噪:使用高斯滤波器对输入图像进行平滑处理,以消除图像中的噪声和细节。高斯滤波器是一种常用的平滑滤波器,它通过卷积操作降低图像噪声。
    • 计算梯度幅值和方向:对平滑后的图像应用Sobel(或Prewitt)算子,计算每个像素点的梯度幅值和方向。梯度可以反映像素值的变化情况,是边缘检测的重要依据。
    • 非极大值抑制:在梯度图像上,对每个像素点在其梯度方向上进行比较,并保留局部最大值点,抑制非边缘像素。这一步的目的是细化边缘,确保边缘的宽度为单个像素。
    • 双阈值处理:根据设定的高阈值和低阈值,将梯度图像中的像素点分为强边缘、弱边缘和非边缘三个部分。高阈值用于确定边缘候选点,而低阈值用于连接边缘。

三、代码实现

  • 对一张图片分别用以上不同的四种算子方法进行实现

    import cv2
    
    """ 读取图片 """
    M = cv2.imread('kobe.jpg', cv2.IMREAD_GRAYSCALE)  # 读取图片并转换为灰度图
    MB = cv2.resize(M, dsize=None, fx=0.4, fy=0.4)  # 对图片大小进行调整(可选)
    
    """ Sobel算子 """
    """
    cv2.Sobel(src, ddepth, dx, dy[,ksize[, scale[, delta[, borderType]]]])# 参数:
    src:输入图像
    ddepth: 输出图像的深度(可以理解为数据类型),-1表示与原图像相同的深度
    dx,dy:当组合为dx=1,du=0时求x方向的一阶导数,当组合为dx=0,dy=1时求y方向的一阶导数(如果同时为1,通常效果不佳)
    ksize:(可选参数)Sobel算子的大小,必须是1,3,5或者7(奇数),默认为3。
    """
    # cv2.Sobel函数来分别计算水平和垂直的梯度
    # 用cv2.CV_64F作为输出图像的深度时,结果可能会包含负数
    MB_x_64 = cv2.Sobel(MB, cv2.CV_64F, dx=1, dy=0)
    MB_y_64 = cv2.Sobel(MB, cv2.CV_64F, dx=0, dy=1)
    # 使用cv2.convertScaleAbs函数将结果转换为可显示的格式(即取绝对值后转换为8位无符号整数)
    MB_x_full = cv2.convertScaleAbs(MB_x_64)
    MB_y_full = cv2.convertScaleAbs(MB_y_64)
    # 使用cv2.addWeighted来结合水平和垂直梯度,这是计算梯度幅度(而非方向)的一种常用方法
    # 权重都设置为0.5,意味着水平和垂直梯度对最终结果的贡献是相同的
    MB_xy_full_Sobel = cv2.addWeighted(MB_x_full, 0.5, MB_y_full, 0.5, 0)  # 可以更改权重得到不同的效果
    
    """ Scharr算子 """
    """
    cv.Scharr(src, ddepth, dx, dyl, dst[, scalel, deltal, borderType]]]])
    src:输入图像
    ddepth:输出图片的数据深度,由输入图像的深度进行选择
    dx: x 轴方向导数的阶数
    dy: y 轴方向导数的阶数
    """
    MB_x_64 = cv2.Scharr(MB, cv2.CV_64F, dx=1, dy=0)
    MB_y_64 = cv2.Scharr(MB, cv2.CV_64F, dx=0, dy=1)
    MB_x_full = cv2.convertScaleAbs(MB_x_64)
    MB_y_full = cv2.convertScaleAbs(MB_y_64)
    MB_xy_full_Scharr = cv2.addWeighted(MB_x_full, 0.5, MB_y_full, 0.5, 0)
    
    """ Laplacian算子 """
    """
    cv2.Laplacian(src, ddepth[, dst[, ksize[, scalel, delta[, borderType]]]]])
    参数说明:
    src:输入图像,可以是灰度图像,也可以是多通道的彩色图像
    ddepth:输出图片的数据深度,由输入图像的深度进行选择
    ksize:计算二阶导数滤波器的孔径大小,必须为正奇数,可选项
    scale:缩放比例因子,可选项,默认值为 1
    delta:输出图像的偏移量,可选项,默认值为 0
    """
    MB_lap = cv2.Laplacian(MB, cv2.CV_64F)
    MB_full_Laplacian = cv2.convertScaleAbs(MB_lap)
    
    """ Canny算子 """
    """
    cv.Canny( image, threshold1, threshold2[, apertureSize[, L2gradient]])
    image 为输入图像
    threshold1 表示处理过程中的第一个阈值。fL --> 低
    threshold2 表示处理过程中的第二个阈值。fH --> 高
    """
    MB_canny = cv2.Canny(MB, 100, 150)  # 设置高低阈值
    
    
    """ 显示结果 """
    cv2.imshow('MB', MB)  # 原图
    cv2.imshow('MB_xy_full_Sobel', MB_xy_full_Sobel)  # Sobel算子
    cv2.imshow('MB_xy_full_Scharr', MB_xy_full_Scharr)  # Scharr算子
    cv2.imshow('MB_full_Laplacian', MB_full_Laplacian)  # Laplacian算子
    cv2.imshow('MB_canny', MB_canny)  # canny算子
    
    # 等待任意键按下后关闭所有窗口
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
  • 结果如下:

    • 原图
      在这里插入图片描述
    • sobel算子(左)和Scharr算子(右)结果图
      在这里插入图片描述
    • Laplacian算子(左)和Canny算子(右)结果图
      在这里插入图片描述
  • 由结果可以看出四个算子中,Canny算子边缘检测的结果是最好的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/872910.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算氨基酸残基之间的键角和二面角

在蛋白质结构中,不同的角度由特定的原子位置决定。常见的原子类型包括氨基酸主链中的 Cα(α 碳)、C(羰基碳)、N(氮原子)和 O(氧原子)。为了更加清晰,下面给出几种常见角度的定义及其对应的原子类型: 使用具体原子的坐标计算键角和二面角 1. 计算 N−Cα−C 的键角…

初次使用住宅代理有哪些常见误区?

随着网络技术的发展,住宅代理因其高匿名性和稳定性成为许多用户进行网络活动的首选工具。然而,对于新手而言,使用住宅代理时往往容易陷入一些误区,这不仅可能影响使用效果,还可能带来安全风险。本文将探讨新手在使用住…

前缀列表(ip-prefix)配置

一. 实验简介 本来前缀列表是要和访问控制列表放在一起讲的,但是这里单拎出来是为了更详细的讲解两者的区别 1.前缀列表针对IP比访问控制更加灵活。 2.前缀列表在后面被引用时是无法对数据包进行过滤的 实验拓扑 二. 实验目的 R4路由器中只引入子网LoopBack的…

oracle数据库安装和配置

​ 大家好,我是程序员小羊! 前言: Oracle 数据库的安装和配置是一个较为复杂的过程,涉及多个步骤和配置项。以下将详细介绍如何在 Linux 和 Windows 系统中安装 Oracle 数据库并进行基础配置。 一、Oracle 数据库安装前的准备 …

提升效率!ArcGIS中创建脚本工具

在我们日常使用的ArcGIS中已经自带了很多功能强大的工具,但有时候遇到个人的特殊情况还是无法满足,这时就可以试着创建自定义脚本工具。 一、编写代码 此处的代码就是一个很简单的给图层更改别名的代码。 1. import arcpy 2. input_fc arcpy.GetParam…

Oracle同义词

默认只能访问自己用户下面的对象,所以可以创建同义词。 同义词(Synonym) 是数据库对象的一个别名,Oracle 可以为表、视图、序列、过程、函数、程序包等指定一个别名 https://blog.csdn.net/ChineseSoftware/article/details/121750937

【springboot】使用缓存

目录 1. 添加依赖 2. 配置缓存 3. 使用EnableCaching注解开启缓存 4. 使用注解 1. 配置缓存名称 2. 配置缓存的键 3. 移除缓存 5. 运行结果 1. 添加依赖 <!-- springboot缓存--><dependency><groupId>org.springframework.boot</groupId>…

ngrok | 内网穿透,支持 HTTPS、国内访问、静态域名

前言 当我们需要把本地开发的应用展示给外部用户时&#xff0c;常常会因为无法直接访问而陷入困境。 就为了展示一下&#xff0c;买服务、域名&#xff0c;搭环境&#xff0c;费钱又费事。 那有没有办法&#xff0c;让客户直接访问自己本机开发的应用呢&#xff1f; 这种需…

分享MSSQL、MySql、Oracle的大数据批量导入方法及编程手法细节

1&#xff1a;MSSQL SQL语法篇&#xff1a; BULK INSERT [ database_name . [ schema_name ] . | schema_name . ] [ table_name | view_name ] FROM data_file [ WITH ( [ [ , ] BATCHSIZE batch_size ] [ [ , ] CHECK_CONSTRAINTS …

基于OMS构建OceanBase容灾双活架构的实践

在实际生产环境中&#xff0c;对于关键业务&#xff0c;往往会有容灾双活的需求。除了OceanBase提供的主备库能力&#xff0c;通过官方工具OMS也可以实现容灾双活架构。目前&#xff0c;通过OMS实现的双活架构仅支持OceanBase数据库之间的数据同步。 要通过OMS实现双活架构&am…

Spring之Bean的生命周期 2024-9-6 19:47

目录 什么是Bean的生命周期为什么要知道Bean的生命周期Bean的生命周期之5步Bean生命周期之7步Bean生命周期之10步 声明&#xff1a;本章博客内容采自老杜2022spring6 语雀文档 什么是Bean的生命周期 Spring其实就是一个管理Bean对象的工厂。它负责对象的创建&#xff0c;对象的…

关于鸿蒙开发中Stage应用模型的相关介绍

应用模型 是系统为开发者提供的应用程序所需能力的抽象提炼&#xff0c;它提供了应用程序必备的组件和运行机制。 简言之&#xff1a;应用模型就是 应用的施工图纸&#xff0c;他规范了&#xff1a;程序运行流程、项目结构、文件功能等…… 了解应用模型之后&#xff0c;就可…

ELK学习笔记(二)——使用K8S部署Kibana8.15.0

上篇文章我们完成了&#xff0c;ES的集群部署&#xff0c;如果还没有看过上篇文章的兄弟&#xff0c;可以去看看。 ELK学习笔记&#xff08;一&#xff09;——使用K8S部署ElasticSearch8.15.0集群 话不多说&#xff0c;接下来直接进入kibana的搭建 一、下载镜像 #1、下载官方…

JS 封装方式

引言&#xff1a;本人是后台服务端开发的&#xff0c;前端的 js 都是在 html 中的 script 标签中写的&#xff0c;处理下数据啥&#xff0c;如果要有需要公共使用的方法啥的都是把方法直接丢在一个 js 文件里&#xff0c;然后 html 引入使用&#xff0c;没有关注过 js 的封装。…

【JavaEE初阶】多线程(2)

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 线程的核心操作 创建线程start 线程的状态 线程的终止 定义一个变量实现 利用标志位实现 加上break/return 结束线程 线程等待 join 无参数版本 两个线程等待 多个线…

如何从 Bak 文件中恢复 SQL数据库?(3种方法)

如何从 .bak 文件恢复 SQL数据库&#xff1f; 在数据库管理和维护过程中&#xff0c;数据的安全性和完整性至关重要。备份文件&#xff08;.bak 文件&#xff09;是 SQL Server 中常用的数据库备份格式&#xff0c;它包含了数据库的完整副本&#xff0c;用于在数据丢失、系统故…

iLogtail 开源两周年:社区使用调查报告

作者&#xff1a;玄飏 iLogtail 作为阿里云开源的可观测数据采集器&#xff0c;以其高效、灵活和可扩展的特性&#xff0c;在可观测采集、处理与分析领域受到了广泛的关注与应用。在 iLogtail 两周年之际&#xff0c;我们对 iLogtail 开源社区进行了一次使用调研&#xff0c;旨…

Java入门:07.Java中的面向对象02

5 对象的使用 对象有两种使用情况 情况一&#xff1a; 对象本身&#xff0c;是一个引用类型的数据 所以他也可以像其他的所有数据一样&#xff0c;进行操作 如&#xff1a;存储&#xff0c;打印等。 int i 10 ; print(10) ; ​ //最终存储在变量中的是对象的地址。 Perso…

歌者PPT新功能速递!

本期功能更新&#xff0c;主要围绕 PPT 大纲编辑器和 PPT 翻译功能&#xff0c;全面提升了制作效率和灵活性&#xff0c;帮助你更轻松地完成 PPT 制作&#xff01;一起来看看吧&#xff5e;&#x1f447; # 功能更新 1 PPT 大纲编辑器全面更新 &#x1f4dd; 现在&#xff0c…

解决Metasploit调用Nessus报错问题

问题描述 Error while running command nessus_scan_new: undefined method []’ for nil:NilClass 解决方法 发现报错&#xff0c;经过网上查询解决方法 在Nessus服务器执行&#xff0c;下面的版本号可能有所不同&#xff0c;根据自己的情况更改&#xff0c;需要管理员身份执…