从零开始学cv-14:图像边缘检测

server/2024/9/24 12:22:30/

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、图像边缘是什么?
  • 二、Sobel 算子
  • 三、Scharr 算子
  • 四、Prewitt算子
  • 五、Canny算子


前言

边缘检测是OpenCV中的一个重要组成部分,它用于识别图像中亮度变化显著的点,即边缘。通过边缘检测,我们可以从图像中提取出重要的特征,为后续的图像分析、形状识别和物体跟踪等任务奠定基础。
在本文中,我们将深入探讨OpenCV中的边缘检测技术,包括其基本原理、常用算法以及实际应用。我们将介绍如何使用OpenCV进行边缘检测,并提供一些示例代码,帮助读者更好地理解和掌握这一技术。


一、图像边缘是什么?

图像边缘是图像中亮度或颜色发生显著变化的区域,它们通常是图像分割和形状识别的基础。边缘检测是计算机视觉和图像处理中的一个关键步骤,用于识别图像中物体与背景之间的边界。
在数字图像中,边缘通常对应于像素值变化显著的区域。这些变化可能是由物体与背景之间的对比度差异引起的,也可能是由于物体形状或纹理的突变。边缘可以分为几种类型:

亮度边缘:这是最常见的边缘类型,它表示图像中亮度值从一个值突然变化到另一个值。
颜色边缘:在彩色图像中,颜色边缘表示颜色从一个颜色突然变化到另一个颜色。
形状边缘:这种边缘是由于物体形状的突变引起的,例如,从一个圆角变成直角。
纹理边缘:在纹理丰富的图像中,纹理边缘是由于纹理图案的突变引起的。
边缘检测算法通常使用各种技术来检测这些边缘。常用的边缘检测算子包括:

  1. Sobel算子:用于检测水平边缘和垂直边缘。
  2. Prewitt算子:类似于Sobel算子,用于检测水平边缘和垂直边缘。
  3. Roberts算子:用于检测水平和垂直边缘。
  4. Canny边缘检测器:这是一个更复杂的边缘检测算法,它能够检测到图像中的所有边缘,并抑制噪声。
    计算机视觉和图像处理中,边缘检测的结果通常用于进一步的图像分析,如轮廓检测、形状识别、图像分割和目标跟踪等。通过提取边缘信息,我们可以更好地理解图像内容,并将其应用于各种实际应用中,下面我们来学习一些常用的边缘检测方法。

二、Sobel 算子

Sobel算子是一种用于边缘检测的算法,它在图像处理中非常常见。它通过计算图像亮度的空间梯度来突出显示图像中的边缘。Sobel算子包含两个核(即卷积矩阵),分别用于检测图像的水平边缘和垂直边缘。
图像的边缘通常对应于梯度的极大值,因此通过计算图像的梯度,我们可以检测到图像中的边缘。Sobel算子通过使用两个3x3的卷积核来近似计算图像的水平和垂直梯度。这两个核分别对图像进行卷积操作,以产生两个梯度分量。
PS:在数学中,梯度是一个向量,表示函数在某一点处的最大变化率。在二维图像中,梯度可以表示为亮度的变化率,并且可以用两个分量来描述:水平方向的变化率(梯度x)和垂直方向的变化率(梯度y)。

Sobel算子通过使用两个3x3的卷积核来近似计算图像的水平和垂直梯度。这两个核分别对图像进行卷积操作,以产生两个梯度分量。在这里插入图片描述
将这两个核分别与图像进行卷积,可以得到两个梯度分量 Gx和 Gy 。然后,可以使用以下公式计算梯度的幅度
在这里插入图片描述
梯度方向 θ 可以通过以下公式计算:
在这里插入图片描述
在OpenCV库中,Sobel函数是一个用于计算图像亮度的空间梯度的函数,它可以用来检测图像中的边缘。dst = cv2.Sobel(src, ddepth, dx, dy, ksize[, scale[, delta[, borderType]]])

src: 输入图像,可以是灰度图像或者彩色图像。如果是彩色图像,Sobel函数会在每个颜色通道上单独计算梯度。
ddepth: 目标图像的所需深度,以下是几个常用的选项:
cv2.CV_8U: 8位无符号整数
cv2.CV_16U: 16位无符号整数
cv2.CV_32F: 32位浮点数
cv2.CV_64F: 64位浮点数 通常使用cv2.CV_64F以避免在计算过程中出现数据溢出。
dx: x方向的差分阶数,取值1或0。1表示计算水平方向的梯度。
dy: y方向的差分阶数,取值1或0。1表示计算垂直方向的梯度。
ksize: Sobel核的大小,必须是正数和奇数,常见的取值为1、3、5或7。如果ksize=-1,则使用3x3的Scharr算子。
scale: 可选参数,用于缩放结果,默认值为1。
delta: 可选参数,用于在结果中添加一个可选的增量值,默认值为0。
borderType: 边界类型,用于处理图像边界,默认值为cv2.BORDER_DEFAULT。

代码:

python">import cv2imgGray = cv2.resize(cv2.imread(r"E:\PS\R-C.jpg", flags=0), (640,480)) # flags=0 灰度图像x = cv2.Sobel(imgGray,-1, 1,0)  # -1代表输入输出同深度 1 0 代表x方向
y = cv2.Sobel(imgGray, -1, 0,1) # -1代表输入输出同深度 0 1 代表y方向
cv2.imshow("dx",x)
cv2.imshow("dy",y)
cv2.waitKey(0)

效果:
在这里插入图片描述

三、Scharr 算子

Sobel算子虽然能有效提取图像边缘,但对于图像中较弱的边缘,其提取效果往往不尽人意。为了更有效地揭示这些细微边缘,需要提升像素值间的对比度,这就引入了Scharr算子。Scharr算子实际上是Sobel算子的一个改进版本,旨在增强其差异性,因此它们在边缘检测的原理和操作方式上是相通的。Scharr算子的边缘检测滤波器尺寸同样为3×3,因而有时也被称为Scharr滤波器。它通过增大滤波器中权重系数,从而放大像素值间的差异,实现了对较弱边缘的更有效提取。以下是Scharr算子在X方向和Y方向的边缘检测算子的示意图。
在这里插入图片描述
opencv中的实现是cv2.Scharr( src, ddepth, dx, dy, scale, delta, borderType)

src: 输入图像,通常是灰度图像。
ddepth: 输出图像的深度,见 cv2.Sobel() 的说明,通常使用 cv2.CV_64F 以避免数据截断。
dx: X方向上的导数阶数,取值1或0。1表示计算水平方向的边缘。
dy: Y方向上的导数阶数,取值1或0。1表示计算垂直方向的边缘。
scale: 可选参数,用于缩放结果,默认值为1。
delta: 可选参数,用于在结果中添加一个可选的增量值,默认值为0。
borderType: 边界类型,用于处理图像边界,默认值为 cv2.BORDER_DEFAULT。

效果:
在这里插入图片描述

四、Prewitt算子

Prewitt算子是图像处理中用于边缘检测的一种算子,与Sobel算子类似,它也是通过计算图像亮度的空间梯度来检测边缘。Prewitt算子使用两个卷积核分别对图像进行卷积操作,以计算水平和垂直方向的梯度。
Prewitt算子与Sobel算子均为边缘检测中常用的梯度算子,然而它们采用的卷积核并不相同。Prewitt算子的卷积核具有较为均匀的权重分布,而Sobel算子的中心位置权重更高,这使得Sobel算子在边缘定位上更为精确。 在检测水平与垂直边缘方面,Prewitt算子展现出对称性,而Sobel算子由于其中心权重的差异,对水平与垂直边缘的检测呈现出一定的偏向性。 在某些特定的情境下,Prewitt算子能描绘出更细腻的边缘细节,这是因为它对各个方向的边缘赋予了同等的权重。
水平梯度:
在这里插入图片描述
垂直梯度:
在这里插入图片描述
代码实现:

python">import cv2
import numpy as np# 读取图像
image = cv2.imread('D:\AI_tool\GFPGAN-master\shenshoushoushitupiansucai_3889318.jpg', cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image,(0,0),fx=0.5,fy=0.5)
# 定义Prewitt算子的卷积核
prewitt_x = np.array([[1, 1, 1], [0, 0, 0], [-1, -1, -1]], dtype=np.float32)
prewitt_y = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=np.float32)# 使用filter2D函数应用Prewitt算子
G_x = cv2.filter2D(image, -1, prewitt_x)
G_y = cv2.filter2D(image, -1, prewitt_y)# 计算梯度幅度
G = np.sqrt(G_x**2 + G_y**2)# 将梯度幅度转换为8位整数以进行显示
G = np.uint8(G)_, thresholded = cv2.threshold(G, 10, 255, cv2.THRESH_BINARY)# 显示图像
cv2.imshow('ori', image)
cv2.imshow('Thresholded Edge Detection', thresholded)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果:在这里插入图片描述

五、Canny算子

Canny边缘检测算法,由John F. Canny于1986年提出,旨在实现一种高效的边缘检测技术,适用于图像处理领域。该算法旨在在减少噪声干扰的同时,精确地识别图像中的边缘。Canny算法的特点包括高检测率、低误报率和低信噪比,这些特点使得它能够有效地检测到图像中的真实边缘,同时抑制噪声和假边缘的产生。

Canny算法的具体步骤如下:

高斯滤波:首先,使用高斯滤波器对图像进行平滑处理,以降低噪声的影响。
计算梯度:接着,使用Sobel算子或其他梯度计算方法计算图像的梯度,梯度的大小表示边缘的强度,方向表示边缘的方向。
非极大值抑制:在梯度图像上应用非极大值抑制,以保留边缘的方向信息,并去除噪声点。这一步骤有助于增强边缘的显著性。
双阈值处理:选择两个阈值,一个较低的阈值和一个较高的阈值。只有当一个像素的梯度值在两个阈值之间时,它才被认为是边缘。这一步骤有助于区分真正的边缘和噪声。
边缘跟踪:使用双阈值处理后的图像来跟踪边缘。在跟踪过程中,如果一个像素的梯度值高于高阈值,则将其视为边缘;如果像素值在两个阈值之间,则将其视为可能的边缘;如果像素值低于低阈值,则不考虑。这一步骤有助于精确地定位边缘的位置。其opencv的api为edges = cv2.Canny(image, lowThreshold, highThreshold)

image: 输入图像,通常是灰度图像。
lowThreshold: 较低的阈值,用于确定边缘的候选点。
highThreshold: 较高的阈值,用于确定边缘的准确位置。

使用代码:

python">import cv2
import numpy as np# 读取图像
image = cv2.resize(cv2.imread(r'D:\AI_tool\GFPGAN-master\shenshoushoushitupiansucai_3889318.jpg', cv2.IMREAD_GRAYSCALE),(0,0),fx=0.5,fy=0.5)# 应用Canny边缘检测
low_threshold = 50
high_threshold = 50
edges = cv2.Canny(image, low_threshold, high_threshold)# 显示图像
cv2.imshow('Original Image', image)
cv2.imshow('Canny Edge Detection', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果:
在这里插入图片描述


http://www.ppmy.cn/server/113510.html

相关文章

QT_ERROR running qmake

文章目录 之前一直以为没有对应的msvc版本。。。。 尝试过网上的其他解答,将qt插件的版本和属性的版本统一没用

洛谷 凸多边形划分

T282062 凸多边形的划分 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 先整一个半成品&#xff0c;高精度过两天复习一下补上 #include <iostream> #include <algorithm> #include <set> #include <cstring> #include <string> #include <…

分类算法可视化方法

可视化方法可以用于帮助理解分类算法的决策边界、性能和在不同数据集上的行为。 下面列举几个常见的可视化方法。 1. 决策边界可视化 这种方法用于可视化不同分类算法在二维特征空间中如何分隔不同类别。对于理解决策树、支持向量机&#xff08;SVM&#xff09;、逻辑回归和…

江协科技STM32学习- P11 中断系统,EXTI外部中断

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

插入、希尔、冒泡、选择排序

目录 1.插入排序 2.希尔排序 3.冒泡排序 4.选择排序 5.完整代码以及时间测试 1.插入排序 即每次把要插入的元素插入已经有序的数组中&#xff0c;经过不断向前比较&#xff0c;来插入目标元素 void InsertSort(int* a, int n) {for (int i 0; i < n-1;i){int end i;…

TeeChart助力科研软件:高效实现数据可视化

在当今的科学研究中&#xff0c;数据可视化已经成为理解和传播复杂信息的关键工具。尤其是在物理研究领域&#xff0c;科学家们经常需要处理大量的数据&#xff0c;并通过可视化将这些数据转化为更易理解的形式。TeeChart作为一个强大且灵活的图形展示工具&#xff0c;能够帮助…

【Unity小技巧】物体遮挡轮廓描边效果

前言&#xff1a; 效果展示&#xff1a; 遮挡描边 Demo下载 所用插件 QuickOutline描边插件&#xff08;在Demo里&#xff09; 实现步骤 物体挂载Outline组件&#xff0c;做如下处理 Outline Mode&#xff08;描边模式&#xff09;&#xff1a;Outline Hidden(遮挡模式显示…

基础学习之——git 的使用方式

git 是一种分布式版本控制系统&#xff08;Distributed Version Control System, DVCS&#xff09;&#xff0c;用于有效地管理代码和文件的变更历史。它最初由林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;于2005年为管理Linux内核开发而设计&#xff0c;并很快因其效率…