Opencv实现Sobel算子、Scharr算子、Laplacian算子、Canny检测图像边缘

图像边缘检测

目录

  • 图像边缘检测
    • [1 Sobel算子](#1 Sobel算子)
      • 1.1概念
      • [1.2 两个卷积矩阵](#1.2 两个卷积矩阵)
      • [1.3 函数及参数理解](#1.3 函数及参数理解)
      • [1.4 灰度图实际测试](#1.4 灰度图实际测试)
      • [1.5 BGR图测试](#1.5 BGR图测试)
    • [2 Scharr算子](#2 Scharr算子)
      • 2.1概念
      • [2.2 实际测试](#2.2 实际测试)
    • [3 Laplacian算子](#3 Laplacian算子)
      • 3.1概念
      • [3.2 函数](#3.2 函数)
      • [3.3 实际测试](#3.3 实际测试)
    • [4 Canny边缘检测](#4 Canny边缘检测)
      • [4.1 概念](#4.1 概念)
      • [4.2 步骤](#4.2 步骤)
      • [4.3 优点](#4.3 优点)
      • [4.4 函数及参数理解](#4.4 函数及参数理解)
      • [4.5 实际测试](#4.5 实际测试)

1 Sobel算子


1.1概念

是一种用于图像处理的算法,主要用于边缘检测。它通过计算图像亮度的空间梯度来突出显示图像中的边缘。Sobel算子包含两个核(卷积矩阵),分别用于检测水平边缘和垂直边缘。

1.2 两个卷积矩阵

1.3 函数及参数理解

  • cv2.Sobel(图片变量,数据类型,dx=1/0,dy=0/1) ,水平/垂直获取轮廓
    • 数据类型为数字-1时,与图片类型相同,为cv2.CV_64F时,为浮点型有正负
    • dx为1时水平获取,dy为1时垂直获取,不能同时为1
  • cv2.convertScaleAbs(轮廓变量),对轮廓变量内的数值绝对值化,使其可以显示出来
  • cv2.addWeighted(x轮廓变量,1,y轮廓变量,1,0),组合轮廓变量使其完整

1.4 灰度图实际测试

代码展示:

python 复制代码
import cv2
yuan = cv2.imread('yuan.png')
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
yuan_1 = cv2.Sobel(yuan,-1,dx=1,dy=0)
yuan_64F = cv2.Sobel(yuan,cv2.CV_64F,dx=1,dy=0)
yuan_Abs = cv2.convertScaleAbs(yuan_64F)
yuan_1_y = cv2.Sobel(yuan,-1,dx=0,dy=1)
yuan_64F_y = cv2.Sobel(yuan,cv2.CV_64F,dx=0,dy=1)
yuan_Abs_y = cv2.convertScaleAbs(yuan_64F_y)
# 组合
yuan_xy = cv2.addWeighted(yuan_Abs,1,yuan_Abs_y,1,0)
cv2.imshow('yuan_1',yuan_1)
cv2.waitKey(0)
cv2.imshow('yuan_64F',yuan_64F)
cv2.waitKey(0)
cv2.imshow('yuan_Abs',yuan_Abs)
cv2.waitKey(0)
cv2.imshow('yuan_1_y',yuan_1_y)
cv2.waitKey(0)
cv2.imshow('yuan_64F_y',yuan_64F_y)
cv2.waitKey(0)
cv2.imshow('yuan_Abs_y',yuan_Abs_y)
cv2.waitKey(0)
cv2.imshow('yuan_xy',yuan_xy )
cv2.waitKey(0)

运行结果:

1.5 BGR图测试

代码展示:

python 复制代码
import cv2
at1 = cv2.imread('at1.png')
cv2.imshow('at1',at1)
cv2.waitKey(0)
at1_64F = cv2.Sobel(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs = cv2.convertScaleAbs(at1_64F)
at1_64F_y = cv2.Sobel(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y = cv2.convertScaleAbs(at1_64F_y)

# 组合
at1_xy = cv2.addWeighted(at1_Abs,1,at1_Abs_y,1,0)
cv2.imshow('at1_64F',at1_64F)
cv2.waitKey(0)
cv2.imshow('at1_Abs',at1_Abs)
cv2.waitKey(0)
cv2.imshow('at1_64F_y',at1_64F_y)
cv2.waitKey(0)
cv2.imshow('at1_Abs_y',at1_Abs_y)
cv2.waitKey(0)
cv2.imshow('at1y_xy_sobel',at1_xy )
cv2.waitKey(0)

运行结果:

2 Scharr算子


2.1概念

它是Sobel算子的一种改进版本,专门用于计算图像的梯度。Scharr算子与Sobel算子的主要区别在于它们的卷积核不同。Scharr算子在处理边缘时比Sobel算子具有更高的精度,但它们在计算时间和复杂度上是一样的,函数cv2.Scharr(),内在参数与Sobel算子相同,同样需要绝对值和组合。

2.2 实际测试

代码展示:

python 复制代码
import cv2
at1 = cv2.imread('at1.png')
cv2.imshow('at1',at1)
cv2.waitKey(0)
at1_64F = cv2.Sobel(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs = cv2.convertScaleAbs(at1_64F)
at1_64F_y = cv2.Sobel(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y = cv2.convertScaleAbs(at1_64F_y)
# # 组合
at1_xy = cv2.addWeighted(at1_Abs,1,at1_Abs_y,1,0)
cv2.imshow('at1y_xy_sobel',at1_xy )
cv2.waitKey(0)
# # scharr
at1_64F_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs_Scharr = cv2.convertScaleAbs(at1_64F_Scharr)
at1_64F_y_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y_Scharr = cv2.convertScaleAbs(at1_64F_y_Scharr)
at1_xy_Scharr = cv2.addWeighted(at1_Abs_Scharr,1,at1_Abs_y_Scharr,1,0)
cv2.imshow('at1y_xy_Scharr',at1_xy_Scharr)
cv2.waitKey(0)

运行结果:

3 Laplacian算子


3.1概念

是一种用于边缘检测的数学工具。在图像处理中,Laplacian算子通常用于找到图像中的亮度快速变化的区域,这些区域往往对应于图像中的边缘或者物体边界。

不需要再进行图片组合。

3.2 函数

  • cv2.Laplacian(图片变量,数据类型)
  • cv2.convertScaleAbs(轮廓变量)

3.3 实际测试

代码展示:

python 复制代码
import cv2
yuan = cv2.imread('yuan.png')
cv2.imshow('yuan',yuan)
cv2.waitKey(0)
at1 = cv2.imread('at1.png')
cv2.imshow('at1',at1)
cv2.waitKey(0)
## Sobel
at1_64F = cv2.Sobel(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs = cv2.convertScaleAbs(at1_64F)
at1_64F_y = cv2.Sobel(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y = cv2.convertScaleAbs(at1_64F_y)
# # # 组合
at1_xy = cv2.addWeighted(at1_Abs,1,at1_Abs_y,1,0)
cv2.imshow('at1y_xy_sobel',at1_xy )
cv2.waitKey(0)
# # # scharr
at1_64F_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs_Scharr = cv2.convertScaleAbs(at1_64F_Scharr)
at1_64F_y_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y_Scharr = cv2.convertScaleAbs(at1_64F_y_Scharr)
at1_xy_Scharr = cv2.addWeighted(at1_Abs_Scharr,1,at1_Abs_y_Scharr,1,0)
cv2.imshow('at1y_xy_Scharr',at1_xy_Scharr)
cv2.waitKey(0)
# laplacian
at1_64F_Laplacian = cv2.Laplacian(at1,cv2.CV_64F)
at1_Abs_Laplacian = cv2.convertScaleAbs(at1_64F_Laplacian)
cv2.imshow('at1_Abs_Laplacian ',at1_Abs_Laplacian )
cv2.waitKey(0)
yuan_64F_Laplacian = cv2.Laplacian(yuan,cv2.CV_64F)
yuan_Abs_Laplacian = cv2.convertScaleAbs(yuan_64F_Laplacian)
cv2.imshow('yuan_Abs_Laplacian ',yuan_Abs_Laplacian )
cv2.waitKey(0)

运行结果:

4 Canny边缘检测


4.1 概念

Canny边缘检测是一种流行的图像处理算法,用于检测图像中的边缘,并被认为是边缘检测中最优的算法之一。

4.2 步骤

  1. 噪声降低
    • 使用高斯滤波器对图像进行平滑处理,以减少图像中的噪声。高斯滤波器可以有效地降低噪声,同时保持边缘的尖锐度。
  2. 计算梯度幅度和方向
    • 通过计算图像中每个像素点的梯度幅度和方向,来确定可能的边缘。通常使用Sobel算子来计算水平和垂直方向的梯度。
  3. 非极大值抑制
    • 对梯度幅度进行非极大值抑制,这一步会沿着梯度方向检查每个像素,只有当该像素的梯度幅度是局部最大值时,才将其保留为边缘候选点,否则将其抑制(即设为0)。
  4. 双阈值确定边缘
    • 应用两个阈值(高阈值和低阈值)来确定真实边缘和潜在边缘。梯度幅度高于高阈值的像素被标记为强边缘,梯度幅度低于低阈值的像素被抑制,梯度幅度在两个阈值之间的像素被标记为弱边缘。
  5. 边缘跟踪和边缘连接
    • 最后,通过边缘跟踪和边缘连接来强化边缘。通常,算法会检查弱边缘像素是否与强边缘像素相连,如果是,则将其标记为强边缘。这个过程可以确保边缘是连续的。

4.3 优点

Canny边缘检测算法的优点包括:

  • 良好的检测效果:Canny算法能够检测到图像中的真实边缘,同时抑制噪声。
  • 边缘定位精度:由于使用了梯度方向,Canny算法能够更精确地定位边缘。
  • 参数可调:通过调整高斯滤波器的大小、阈值等参数,可以适应不同的图像和边缘检测需求。

Canny边缘检测算法在计算机视觉和图像处理领域得到了广泛应用,尤其是在需要精确边缘检测的场合。

4.4 函数及参数理解

  • cv2.Canny(图像变量,低阈值,高阈值),低于低阈值为0,高于高阈值为255

4.5 实际测试

代码展示:

python 复制代码
import cv2
at1 = cv2.imread('at1.png')
cv2.imshow('at1',at1)
cv2.waitKey(0)
at1_64F = cv2.Sobel(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs = cv2.convertScaleAbs(at1_64F)
at1_64F_y = cv2.Sobel(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y = cv2.convertScaleAbs(at1_64F_y)
#
# # # 组合
at1_xy = cv2.addWeighted(at1_Abs,1,at1_Abs_y,1,0)
cv2.imshow('at1y_xy_sobel',at1_xy )
cv2.waitKey(0)
# #
# # scharr
at1_64F_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=1,dy=0)
at1_Abs_Scharr = cv2.convertScaleAbs(at1_64F_Scharr)
at1_64F_y_Scharr = cv2.Scharr(at1,cv2.CV_64F,dx=0,dy=1)
at1_Abs_y_Scharr = cv2.convertScaleAbs(at1_64F_y_Scharr)
at1_xy_Scharr = cv2.addWeighted(at1_Abs_Scharr,1,at1_Abs_y_Scharr,1,0)
cv2.imshow('at1y_xy_Scharr',at1_xy_Scharr)
cv2.waitKey(0)
# laplacian
at1_64F_Laplacian = cv2.Laplacian(at1,cv2.CV_64F)
at1_Abs_Laplacian = cv2.convertScaleAbs(at1_64F_Laplacian)
cv2.imshow('at1_Abs_Laplacian ',at1_Abs_Laplacian )
cv2.waitKey(0)
# # canny
at1_canny = cv2.Canny(at1,130,255)
cv2.imshow('at1_canny',at1_canny )
cv2.waitKey(0)

运行结果:

相关推荐
engchina5 分钟前
使用 `llama_index` 构建智能问答系统:多种文档切片方法的评估
python·openai·llama·代码优化·rag
顾道长生'7 分钟前
(NIPS-2023)ProlificDreamer:通过变分分数蒸馏实现高保真、多样化的文本到 3D 生成
计算机视觉·3d·扩散模型
微学AI10 分钟前
GPU算力平台的应用之任意门:任意穿搭匹配模型的应用教程
服务器·人工智能·gpu算力
莫宰特12 分钟前
人脑神经元的连接方式与视觉提取功能对深度学习的启发
人工智能·深度学习
云空19 分钟前
《探秘计算机视觉与深度学习:开启智能视觉新时代》
人工智能·深度学习·神经网络·计算机视觉
沙漏AI机器人24 分钟前
【20250103】AI驱动的通用下肢外骨骼机器人系统以实现社区步行辅助
人工智能·深度学习·机器人
Dann Hiroaki25 分钟前
文献分享:BGE-M3——打通三种方式的嵌入模型
数据库·人工智能·深度学习·自然语言处理·全文检索·bert
xm一点不soso27 分钟前
ROS2+OpenCV综合应用--10. AprilTag标签码追踪
人工智能·opencv·计算机视觉
回音谷36 分钟前
【算法】克里金(Kriging)插值原理及Python应用
python·算法·插值
迷路爸爸18042 分钟前
深入理解 PyTorch 的 Dataset 和 DataLoader:构建高效数据管道
人工智能·pytorch·python