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

news2024/11/15 3:28:58

文章目录

  • 一、图像边缘检测概述
  • 二、常见的图像边缘检测算法(简单介绍)
    • 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算子边缘检测的结果是最好的

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【运维监控】prometheus+node exporter+grafana 监控linux机器运行情况(1)

本示例是通过prometheus的node exporter收集主机的信息,然后在grafana的dashborad进行展示。本示例使用到的组件均是最新的,下文中会有具体版本说明,linux环境是centos。本示例分为四个部分,即prometheus、grafana、node exporter…

南京网站建设自己网站

南京是一座古老而又现代化的城市,拥有悠久的历史和文化底蕴。在这个信息时代,网站已经成为了企业和个人宣传推广的重要途径之一。南京网站建设作为一种推广方式,不仅能够展示企业形象,还能够传递信息、吸引客户、增加销售。 南京网…

Spring Boot-自定义banner

在 Spring Boot 应用中,你可以自定义启动时显示的 banner。这些 banner 可以包括图形、文字或者其他形式的标识。如图所示: 1. 使用 banner.txt 文件 默认情况下,Spring Boot 使用项目的 banner.txt 文件中的内容作为启动时的 banner。你可以…

计算机岗位(面试)

计算机岗位(面试) 计算机主要有哪几部分构成?计算机组成原理的内容? 计算机主要由‌硬件和软件‌两大部分构成。‌硬件部分包括五大基本组件:‌‌运算器、‌控制器、‌存储器、‌输入设备和输出设备‌‌。‌具体来说&a…

用户变渠道,Xinstall引领手游推广新潮流

随着手游市场的日益繁荣,手游推广方式也在不断革新。从传统的地推、广告投放到如今新兴的CPA(按动作付费)和CPS(按销售订单付费)模式,手游推广正逐步走向效果导向的时代。而在这个过程中,Xinsta…

云计算41——部署project_exam_system项目(续)

# 创建脚本,可以在java环境中运行任何的jar包或者war包 #!/bin/bash /usr/local/jdk/bin/java -jar /java/src/*.?ar 一、思路分析 (1)nginx 1、下载镜像,将本地的dist项目的目录挂载在容器的/usr/share/nginx/html/ 2、启…

关于电力系统的几个疑问

非电力专业人员对于电力中的某些知识不能够形成系统的认识,接下有空也有补充下这方面知识,吹水时候才有水可以吹,嘻嘻!这里舍不得删掉下边chatgpt这几张图片,暂时先保留着。因为一直有个因为在电网里边用发电端和用电端…

【笔试强训】—— BM1 反转链表

🌏博客主页:PH_modest的博客主页 🚩当前专栏:笔试强训 💌其他专栏: 🔴每日一题 🟡 C跬步积累 🟢 C语言跬步积累 🌈座右铭:广积粮,缓称…

【从头写CAD】3 长度类

文章目录 一、说明二、源码三、运行和调试结果 一、说明 长度的国际单位是“米”(符号“m”),常用单位有毫米(mm)、厘米(cm)、分米(dm)、千米(km&#xff09…

装WebVideoCreator记录

背景,需要在docker容器内配置WebVideoCreator环境,配置npm、node.js https://github.com/Vinlic/WebVideoCreatorWebVideoCreator地址:https://github.com/Vinlic/WebVideoCreator 配置环境,使用这个教程: linux下安…

非负矩阵分解

非负矩阵分解 简单来说,就是一个数据矩阵X,也可以理解为特征矩阵,将这个矩阵分解为两个非负矩阵W和H的乘积。 公式可以写成下面: 这里的m和n就是特征的维度,r表示代码中n_components参数 来看个例子: 看看…

office套件打开时 提示操作系统当前的配置不能运行此应用程序

起因使用了腾讯电脑管家的软件搬家功能。 许久后发现打开word提示。 随后使用软件搬家功能中的搬移历史中还原office套件。 依然不可用(未尝试重启 大概率重启之后就可以用了 使用的电脑不方便重启) 安装office简易修复工具 地址:https://a…

C++相关概念和易错语法(31)(特殊类的设计、new和delete底层调用分析)

特殊类的设计 在实践过程中,我们难免会接触到一些需要实现特定功能的类。像之前提过的unique_ptr就是直接delete拷贝构造和赋值函数。下面会分享一些常见的特殊类的实现 1、防拷贝和防赋值 通过封死拷贝构造和赋值函数来保护对象里面内容不被复制。如果对象里面的…

JS 对象深浅拷贝

1. 浅拷贝的原理和实现 自己创建一个新的对象,来接受你要重新复制或引用的对象值。如果对象属性是基本的数据类型,复制的就是基本类型的值给新对象;但如果属性是引用数据类型,复制的就是内存中的地址,如果其中一个对象…

从0开始学杂项 第八期:流量分析(2) 数据提取

Misc 学习(八) - 流量分析:数据提取 这一期,我们主要写一下如何进行比较繁多的数据的提取。 使用 Tshark 批量提取数据 有时候,我们会需要从多个包中提取数据,然后再进行截取和组合,比如分析…

千云物流 -低代码平台MySQL备份数据

windows备份 全量备份 创建备份目录 需要在安装数据库的服务器上创建备份目录,所有如果要做备份至少需要两倍的硬盘空间, mkdir D:\mysql_backup\full_backup准备备份脚本 创建一个windows批处理文件(例如 full_backup.bat),用来执行全量备份并使用 robocopy 将备份文件…

HTTP 一、基础知识

一、概述 1、概述 HTTP(Hyper Text Transfer Protocol): 全称超文本传输协议,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP 是一种应用层协议,是基于 …

VUE3 使用 <transition> 实现组件切换的过渡效果

由于我想在项目中实现路由组件切换时的平滑过渡效果&#xff0c;以避免页面加载时的突兀感&#xff0c;大致效果如下&#xff1a; 上面的代码是使用的若依的代码&#xff0c;代码具体如下所示&#xff1a; <section class"app-main"><transition name&quo…

HarmonyOS开发移动应用:调用百度翻译开放平台的App Id和密钥

介绍 通过http请求和HarmonyOS自带的加密框架&#xff0c;可以为移动应用实现调用百度翻译API的功能。 开发环境要求 • DevEco Studio版本&#xff1a;DevEco Studio 3.1 Release • HarmonyOS SDK版本&#xff1a;API version 9 工程要求 • API9 • Stage模型 正文 ▍代码…

QT+OSG+osg-earth显示一个球

目录 1、环境配置 2、在QT Creator导入相关的库 3、代码部分 4、运行过程中的问题 5、相关参考 重要衔接&#xff1a;QTOSG显示一个三维模型-CSDN博客 1、环境配置 系统&#xff1a;windows10系统 QT:版本5.15.2 编译器&#xff1a;MSVC2019_64bit 编辑器…